【Codeforces Round #525(Div. 2)】Ehab and another another xor problem(思维+异或)

题目链接

D. Ehab and another another xor problem

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

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 a⊕c>b⊕da⊕c>b⊕d.
  • 0 if a⊕c=b⊕da⊕c=b⊕d.
  • -1 if a⊕c<b⊕da⊕c<b⊕d.

Operation a⊕ba⊕b is the bitwise-xor operation of two numbers aa and bb.

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

It's guaranteed that 0≤a,b<2300≤a,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 bb (0≤a,b<230)(0≤a,b<230).

Example

input

Copy

1
-1
0

output

Copy

? 2 1
? 1 2
? 2 0
! 3 1

Note

In the sample:

The hidden numbers are a=3a=3 and b=1b=1.

In the first query: 3⊕2=13⊕2=1 and 1⊕1=01⊕1=0, so the answer is 1.

In the second query: 3⊕1=23⊕1=2 and 1⊕2=31⊕2=3, so the answer is -1.

In the third query: 3⊕2=13⊕2=1 and 1⊕0=11⊕0=1, so the answer is 0.

Then, we printed the answer.

 

【题意】

你可以询问最多62个问题,每个问题描述为两个数c,d。系统会给出a xor c 与b xor d的大小关系,询问最多62个问题后输出a,b。

【解题思路】

参考博主:https://blog.csdn.net/qq_40791842/article/details/84836891

可以说写的很明白了。有些地方可能需要手动写一下方便更好的理解。

做这题的时候需要从高位向低位遍历,考虑到只有30位但有62次询问,可以简化成每一次询问先询问当前位到最低位a和b的大小,比较出大小之后再确定当前位是1还是0。

那么如何比较当前位到最低位之间a和b的大小呢?只要记a当前位到最高位的值为c,同理记b当前位到最高位的值为d,异或一下就行啦。比如a:10101,b:11001,假设从高到低位次依次为43210。假设本次比较的是第3位,那么c为10000,d为11000,将a异或c为00101,d异或b为00001,其实就是消去高位到当前位的影响啦。

然后就要确定当前位是1还是0啦。

①ask(prea,preb)=0

   表示从当前位至最低位的所有位ab在该位都对应相等,那么只用判断每一位是0还是1就行了。可以ask(prea+(1<<i),preb)。

   若为-1,该位是1;若为1,该位是0。

②ask(prea,preb)=1

   表示当前位至最低位的二进制数a>b,设a的当前位为a[ i ],b为b[ i ],那么只会存在以下三种情况:
   (1) a[ i ]=1,b[ i ]=0;
   (2) a[ i ]=1,b[ i ]=1;
   (3) a[ i ]=0,b[ i ]=0;

   那么接下来怎么判断呢?

   可以ask(prea+(1<<i),preb+(1<<i));

   <1> 如果等于-1, 那么一定有a[ i ]=1, b[ i ]=0;

   <2> 如果等于1, 那么可以是第(2) (3)两种中的其中一种;继续ask(prea+(1<<i),preb);若为-1,则表明a[ i ]=b[ i ]=1,否则为0

③ask(prea,preb)=-1

   和第2种情况类似!

但是要注意并不是遍历到每一位都要去ask(prea,preb),比如,如果确定当前位 a[ i ]=b[ i ]=1或者a[ i ]=b[ i ]=0,那么下一位ask(prea,preb)的值是和当前的值是一样的,所以循环到下一位的时候就不需要ask了,只有a[ i ] !=b[ i ]的时候下一位才需要重新ask。

【代码】

#include<bits/stdc++.h>
using namespace std;
int ask(int c,int d)
{
    int flag;
 	printf("? %d %d\n",c,d);
	fflush(stdout);
	scanf("%d",&flag);
	return flag;
}
int main()
{
    int prea=0,preb=0;
    int flag=ask(prea,preb);
    for(int i=29;i>=0;i--)
    {
        if(flag==0)
        {
            int flag2=ask(prea+(1<<i),preb);
            if(flag2==-1)
            {
                prea+=(1<<i);
                preb+=(1<<i);
            }
        }
        else if(flag==1)
        {
            int flag2=ask(prea+(1<<i),preb+(1<<i));
            if(flag2==1)
            {
                int flag3=ask(prea+(1<<i),preb);
                if(flag3==-1)
                {
                    prea+=(1<<i);
                    preb+=(1<<i);
                }
            }
            else
            {
                prea+=(1<<i);
                flag=ask(prea,preb);
            }
        }
        else
        {
            int flag2=ask(prea+(1<<i),preb+(1<<i));
            if(flag2==-1)
            {
                int flag3=ask(prea+(1<<i),preb);
                if(flag3==-1)
                {
                    prea+=(1<<i);
                    preb+=(1<<i);
                }
            }
            else
            {
                preb+=(1<<i);
                flag=ask(prea,preb);
            }
        }
    }
	printf("! %d %d\n",prea,preb);
	fflush(stdout);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值