• D. Game with modulo 交互题(取余(膜)性质)附带a mod b<a/2证明


    D. Game with modulo 交互题(取余(膜)性质)

    题意

    猜一个点(a)可以向机器提问 点对((x,y))
    如果(xmod(a)>=ymod(a))回答(x)
    反之回答(y)
    询问不能超过60下,请你猜出a

    思路

    (amod(b)<a/2(a>=b))
    形式化的证明: a的二进制形式是1xxxxxx b的二进制形式是0001xxx
    (a=b*k+x) 设a和b最高位二进制的位数差为(z)
    (k=1<<(z-1))
    这时 b*k的二进制形式是01xxx000
    (a-b*k=x) 其中(b*k>=a/2) 所以(x<=a/2)
    再来讨论相等的情况
    假设(x=a/2)
    所以(x>=b) 所以(xmod(b)<b<a/2)
    也就是(b*k+xmod(b)<a/2)
    也就是(amod(b)<a/2) 故得证
    所以本题中 只要枚举(0,1) (1,2)(2,3) 第一个使得返回y的范围里面 有a,然后二分再找a即可

    #include<bits/stdc++.h>
    #define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;i++)
    #define MS(arr,arr_value) memset(arr,arr_value,sizeof(arr)) 
    #define F first 
    #define S second
    #define pii pair<int ,int >
    #define mkp make_pair
    #define pb push_back
    using namespace std;
    typedef long long ll;
    string opt;
    int main(){
    	while(cin>>opt){
    		if(opt[0]=='s'){
    			
    			ll l=0,r=1;
    			for(;;){
    				cout<<"? "<<l<<" "<<r<<endl;
    				fflush(stdout);
    				cin>>opt;
    				if(opt=="x")break;
    				l=r;
    				r<<=1;
    			}
    			while(l<r){
    				ll mid=l+r>>1;
    				cout<<"? "<<mid<<" "<<r<<endl;
    				fflush(stdout);
    				cin>>opt;
    				if(mid+1==r){
    					cout<<"! ";
    					if(opt=="x"){
    						cout<<r<<endl;
    					}
    					else cout<<mid<<endl;
    					break;
    				}
    				if(opt=="x"){
    					l=mid;
    				}
    				else if(opt=="y")r=mid;
    
    			}
    
    		}
    		else if(opt[0]=='e')break;
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    html的一些基本属性介绍
    html的一些基本语法学习与实战
    getline()和get()的使用区别
    浅谈JS执行环境及作用域
    vue的第一个commit分析
    移动端适配-rem(新)
    电商类业务梳理
    不同类型的状态码及含义
    TCP/IP简记
    前端性能优化小结(持续更新)
  • 原文地址:https://www.cnblogs.com/ttttttttrx/p/10800618.html
Copyright © 2020-2023  润新知