zoukankan      html  css  js  c++  java
  • Codeforces Round #525 D

    题目大意:

    本题有两个隐藏起来的a b(1<=a,b<=1e30)

    每次可 printf("? %d %d ",c,d); 表示询问 a^c 与 b^d 的相对大小 最多可询问62次

    然后 scanf("%d",&ans); 读入返回的答案 

    ans=1 说明 a^c > b^d

    ans=0 说明 a^c = b^d

    ans=-1 说明 a^c < b^d

    当通过询问确定了a b就 printf("! %d %d ",a,b); 表示得到答案为 a b

    input
    Copy
    1
    -1
    0
    output
    Copy
    ? 2 1
    ? 1 2
    ? 2 0
    ! 3 1

    询问 a^2 与 b^1 得到 1

    询问 a^1 与 b^2 得到 -1

    询问 a^2 与 b^0 得到 0

    就可以确定隐藏的 a=3 b=1

    代码里有详细注释

    这里我们举个简单的栗子

    一开始 a^0比较b^0 可得到a b的相对大小 此时假设a>b

    a>b时则a b第i位有三种可能 

    取反最高位后再判断a b的相对大小

    a   b   

    1   1   (a b都取反)-> 0  0   (再比较a b可得到a>b) -> 无法确定(1式)

    1   0   (a b都取反)-> 0  1   (再比较a b可得到a<b) -> 可说明ai=1 bi=0  

    0   0   (a b都取反)-> 1  1   (再比较a b可得到a>b) -> 无法确定(2式)

    (1式) (2式) 无法确定 继续询问

    a   b    

    1   1   (a取反)-> 0  1   (再比较a b可得到a<b) -> 可说明ai=1 bi=1 

    0   0   (a取反)-> 1  0   (再比较a b可得到a>b) -> 可说明ai=0 bi=0 

    如 

    a=1101 b=1011(a>b)

    取反a b第一位 a=0101 b=0011 询问可得a>b 无法判断

    此时只取反a的第一位 a=0101 b=1011 询问可得a<b 说明a的第一位为1 b的第一位为1

    第一位已确定 去掉第一位a=101 b=011(a>b)

    那么取反此时a b第二位 a=001 b=111 询问可得a<b 说明a的第二位为1 b的第二位为0

    第二位已确定 去掉第二位a=01 b=11(a<b)

    那么取反此时a b第三位 a=11 b=01 询问可得a>b 说明a的第三位为0 b的第三位为1

    第三位 已确定 去掉第三位 a=1 b=1(a<b)

    那么取反此时a b第四位 a=0 b=0 询问可得a=b 无法判断

    此时只取反a的第四位 a=0 b=1 询问可得a<b 说明a的第四位为1 b的第四位为1

    最终得到a b

    #include <bits/stdc++.h>
    using namespace std;
    int a, b;
    int maybe(int c,int d) {
        printf("? %d %d
    ",c,d);
        fflush(stdout);
        int ans; scanf("%d",&ans);
        return ans;
    }
    int main()
    {
        int f=0,la=0,lb=0;
        for(int i=29;i>=0;i--) {
            // la lb为a b二进制第i位往左 包含第i位为lai lbi
            // ra rb为a b二进制第i位往右 包含第i为为rai rbi
            // ai bi为a b二进制第i位
            if(f==0) { // f=0时去判断rai rbi的相对大小
                if(maybe(la,lb)==-1) f=-1; // rai<rbi
                else f=1; // rai>=rbi
            }
            if(f==1) {
                /* 已知 rai >= rbi
                    则a b第i位有三种可能
                    ai  bi  (将ai bi取反 la^(1<<i)  lb^(1<<i))
                    1   1   -> 0  0   -> maybe(la,lb)=1或0 (1式)
                    1   0   -> 0  1   -> maybe(la,lb)=-1即rai<=rbi  -> 可得到ai=1 bi=0 此时ra rb的相对大小则不确定了
                    0   0   -> 1  1   -> maybe(la,lb)=1或0 (2式)
                    (1式)=(2式) 无法确定
                    ai  bi  (只将ai取反 la^(1<<i) )
                    1   1   -> 0  1   -> maybe(la,lb)=-1即rai<=rbi  -> 可得到ai=1 bi=1 此时ra rb的相对大小仍不变
                    0   0   -> 1  0   -> maybe(la,lb)=1或0即rai>=rbi-> 可得到ai=0 bi=0 此时ra rb的相对大小仍不变
                将得到的结果更新到la lb 然后i继续往右判断 */
                if(maybe(la^(1<<i),lb^(1<<i))==-1)
                    la^=(1<<i), f=0; // 下轮i往右 需要判断rai rbi的相对大小
                else if(maybe(la^(1<<i),lb)==-1)
                    la^=(1<<i), lb^=(1<<i);
            } else {
                /* f=-1同理f=1 相反过来判断 */
                if(maybe(la^(1<<i),lb^(1<<i))!=-1)
                    lb^=(1<<i), f=0; // 下轮i往右 需要判断rai rbi的相对大小
                else if(maybe(la,lb^(1<<i))==1)
                    la^=(1<<i), lb^=(1<<i);
            }
        }
        printf("! %d %d
    ",la,lb);
        fflush(stdout);
    
        return 0;
    }
    View Code
  • 相关阅读:
    一个bug案例分析
    《需求工程》阅读随笔-1.做什么和怎么做
    连贯接口(fluent interface)的Java实现及应用。
    代码覆盖率检测工具大全
    腾讯的一个移动端测试小工具GT
    用复制mysql/data 文件夹 下面的数据库的形式来复制数据库出现的问题
    淘客API升级后的解决方案,怎么采集淘宝的商品数据
    方维团购系统,给供货商添加省市地址
    支付宝担保交易收款接口使用
    方维分享系统首页,插入新品,用来做优化
  • 原文地址:https://www.cnblogs.com/zquzjx/p/10070529.html
Copyright © 2011-2022 走看看