zoukankan      html  css  js  c++  java
  • D. Game with modulo 交互题

    D. Game with modulo 交互题

    题目大意:

    题目:未知一个数 (a),让你每次猜两个数 (x) 和$ y$,若 ((xmod a)ge (ymod a)) 返回 x,否则返回 y。让你猜测次数少于60次的时候猜出数 (a)

    题解:

    交互题,这个算是我最不会写也不太想写的题目之一了。

    还是有点难的,接下来说说我看了这么多的博客之后的想法。

    img

    首先很容易的发现这个就是一个周期为a的函数,图像如上。

    所以每次找 (i) ,如果 (i*2mod\,a <=imod\,a) ,那么显然易见,在区间 ([i,i*2]) 有且仅有一个值 $xmod,a = 0 $ ,那么从小到大找到的第一个 (x),这个 (x=a)

    接下来贴一下证明:https://www.cnblogs.com/ttttttttrx/p/10800618.html

    好像不是那么容易理解,接下来我简单说说。

    • (amod \,b<a/2(a>=b))(a-b*k=x)
    • 其中 (b*k>=a/2) ,应该可以缩小成 (b*k>a/2),这个是因为如果(b*k<=a/2) ,那么 (2*b*k<=a),所以 (b*k>a/ 2), 所以 (x<a/2)
    • 所以 (amod\,b<a/2(a>=b))
    • 如果 (a<b) ,那么 (amod \,b<a/2(a>=b)) 一定不成立,因为 (amod\,b=a>a/2)
    • 综上所述,从小到大找,找到的第一个 (i*2mod\,a <=imod\,a) ,那么 (a) 一定在区间 ([i,2*i]) 之间
    • 最后说说为什么是每次找 ([2^i,2^{i+1}]) ,因为如果 ([2^{i-1},2^i]) 没有找到,说明 (2^i<a) 那么 区间 ([2^i,2^{i+1}]) 一定最多一个点 (x),使得 (xmod\,a=0)

    所以说,如果找到了一个 (i*2mod\,a <=imod\,a) ,那么 (i*2>a) 一定成立。

    这个之后就是一个二分,这个二分比较特别,因为我已经知道 (imod\,a>i*2mod\,a) ,并且 (2*i>a & i<a) ,所以我每次枚举 ([mid,r])

    如果结果是 (r),那么说明已经应该是 (r) 变小,如果结果是 (mid) 那么说明 (l) 可以变大,自行领悟吧。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e3+10;
    typedef long long ll;
    char s[10];
    int main(){
        while(true){
            scanf("%s",s+1);
            if(s[1]=='s'){
                ll l = 0,r = 1;
                for(int i=1;i<=35;i++){
                    printf("? %lld %lld
    ",l,r);
                    fflush(stdout);
                    scanf("%s",s+1);
                    if(s[1]=='x') break;
                    //如果等于x,表示i mod a > i*2 mod a 
                    l = r,r <<= 1;
                }
                ll ans=0;
                while(l<=r){
                    ll mid=(l+r)>>1;
                    printf("? %lld %lld
    ",mid,r);
                    fflush(stdout);
                    scanf("%s",s+1);
                    if(mid+1==r){
                        if(s[1]=='x') ans = r;
                        //如果 mid mod a > r mod a,因为答案ans一定是 ans%a = 0,所以更小的这个应该是答案
                        else ans = mid;
                        break;
                    }
                    else if(s[1]=='x') l = mid;
                    else r = mid;
                }
                printf("! %lld
    ",ans);
                fflush(stdout);
            }
            else break;
        }
        return 0;
    }
    /*
    input
    
    start
    x
    x
    start
    x
    x
    y
    start
    x
    x
    y
    y
    end
    
    
    output
    ? 0 0
    ? 10 1
    ! 1
    ? 0 0
    ? 3 4
    ? 2 5
    ! 2
    ? 2 4
    ? 2 5
    ? 3 10
    ? 9 1
    ! 3
    
     */
    
  • 相关阅读:
    mysql索引
    springboot mybatis 后台框架平台 shiro 权限 集成代码生成器
    java 企业网站源码模版 有前后台 springmvc SSM 生成静态化
    java springMVC SSM 操作日志 4级别联动 文件管理 头像编辑 shiro redis
    activiti工作流的web流程设计器整合视频教程 SSM和独立部署
    .Net Core中的ObjectPool
    文件操作、流相关类梳理
    .Net Core中的配置文件源码解析
    .Net Core中依赖注入服务使用总结
    消息中间件RabbitMQ(一)
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/13389735.html
Copyright © 2011-2022 走看看