zoukankan      html  css  js  c++  java
  • Codeforces Round #525 (Div. 2)D. Ehab and another another xor problem

    D. Ehab and another another xor problem

    题目链接https://codeforces.com/contest/1088/problem/D

    Description:

    This is an interactive problem!

    Ehab plays a game with Laggy. Ehab has 2 hidden integers (a,b)(a,b). Laggy can ask a pair of integers (c,d)(c,d) and Ehab will reply with:

    • 1 if ac>bd.
    • 0 if ac=bd.
    • -1 if ac<b⊕d.

    Operation ab is the bitwise-xor operation of two numbers aa and bb.

    Laggy should guess (a,b) with at most 62 questions. You'll play this game. You're Laggy and the interactor is Ehab.

    It's guaranteed that 0a,b<230.

    Input

    See the interaction section.

    Output

    To print the answer, print "! a b" (without quotes). Don't forget to flush the output after printing the answer.

    Interaction

    To ask a question, print "? c d" (without quotes). Both cc and dd must be non-negative integers less than 230230. Don't forget to flush the output after printing any question.

    After each question, you should read the answer as mentioned in the legend. If the interactor replies with -2, that means you asked more than 62 queries and your program should terminate.

    To flush the output, you can use:-

    • fflush(stdout) in C++.
    • System.out.flush() in Java.
    • stdout.flush() in Python.
    • flush(output) in Pascal.
    • See the documentation for other languages.

    Hacking:

    To hack someone, print the 2 space-separated integers aa and b(0a,b<230)(0≤a,b<230).

    题意:

    交互式题目。有两个隐藏的数a,b,每次可以给出询问"? c d",然后返回:

    1.若a^c>b^d,返回1;

    2.若a^c=b^d,返回0;

    3.若a^c<b^d,返回-1。

    然后最多进行62次操作,最终问a,b是多少?

    题解:

    我的第一道交互式题目~这题还是挺有意思的。

    a,b最多小于2^30,并且操作次数最多62次,我们可以想到一位一位来分析。

    然后模拟一下:

    当a,b二进制中目前位置都为1时,分别异或1,0和0,1,那么肯定返回的是-1,1;

    当a,b二进制中目前位置都为0时,分别异或1,0和0,1,返回的是1,-1;

    当a,b二进制中目前位置不同时,异或1,0和0,1的结果是相同的,但正负并不一定。

    我们现在主要考虑二进制中目前位置不同的情况,这种较为复杂,假设我们已知a>b,那么最高位不同时,肯定a的最高位是1,b的相同位置是0。

    那么问题转化为了如何找a,b大小。

    我们知道一开始的时候都异或0,0可以轻松地比较出a,b的大小,在之后第一次碰到不相同的情况(询问结果返回的值相同),可以确定;如果还能碰到第二次,那么就可以根据上一次的询问结果来判断大小(在第一次中异或后a,b的最高位变为相同的了,它会返回一个比较值,这个比较值就是后面二进制位数相比较的大小)。

    每次找最高位,把当前位置之前的给异或掉就行了。

    代码如下:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    
    int query(int a,int b){
        printf("? %d %d
    ",a,b);
        fflush(stdout);
        int tmp;
        scanf("%d",&tmp);
        return tmp;
    }
    
    int main(){
        int a=0,b=0;
        int big = query(a,b);
        for(int i=29;i>=0;i--){
            int x=query(a^(1<<i),b),y=query(a,b^(1<<i));
            if(x==y){
                if(big>0) a^=(1<<i);
                else b^=(1<<i);
                big=(x==1);
            }else{
                if(x==-1) a^=(1<<i),b^=(1<<i);
            }
        }
        printf("! %d %d",a,b);
        return 0;
    }
  • 相关阅读:
    React中的PropTypes详解
    mobile 更改hosts
    sed用例
    Centos 7 开启端口
    node-gyp rebuild 卡住?
    录制客户端脚本
    创建删除表空间以及表空间使用情况查询
    oracle 修改字符集 修改为ZHS16GBK
    linux中压缩、解压缩命令详解
    jps、jstack、jmap、jhat、jstat、hprof使用详解
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10079795.html
Copyright © 2011-2022 走看看