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;
    }
  • 相关阅读:
    linux可执行文件添加到PATH环境变量的方法
    PHPExcel所遇到问题的知识点总结
    如何查看已经安装的nginx、apache、mysql和php的编译参数
    oracle 创建用户及表空间命令
    datetimepicker 设置日期格式、初始化
    Linux 修改系统时间(自动同步)
    Nginx 负载均衡配置
    CenterOS7 安装 Nginx【转】
    java https post请求并忽略证书,参数放在body中
    将.cer证书导入java密钥库?
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10079795.html
Copyright © 2011-2022 走看看