zoukankan      html  css  js  c++  java
  • Codeforces 835E. The penguin's game

    http://codeforces.com/problemset/problem/835/E

    题意:

    这是一道交互题

    有n个数,其中有2个y,n-2个x

    每次你可以询问若干个数的异或和,从而得出y的位置

    最开始给出n,x,y

    最多询问19次

    多猪试毒问题:

    有1000瓶药,其中只有1瓶是解药,其他的都是毒药

    你有一些猪,今天让他们会喝下若干瓶药,所有没有喝到解药的猪会在明天的同一时刻死去

    问最少需要多少头猪一定会试出哪瓶是解药

    答案是10头

    因为不同的数的二进制位至少有一位不相同

    10位二进制可表示1000以内的所有的数

    让第i头猪喝下所有第i位二进制位为1的药

    如果明天第i头猪没有死,就可以确定解药的第i位二进制位为1

    这道题相当于是有两瓶解药,而且如果喝下两瓶解药会变成毒药

    让你构造一种喝药的方案,用至多19头猪找出解药

    如果我们能想办法找到一堆药,使得这里面有且只有一瓶解药,那就可以套用上面的方法了

    同样的方法,两瓶解药的二进制位至少有一位不同

    如果有一头猪没有死,那么它所喝下的药里一定只有一瓶解药,它没喝的药里面也有且仅有一瓶解药

    最多用10头猪就可以找到这样的一头猪

    它喝的药 和 没喝的药 数量少的那一组里套用一次上面的多猪试毒的方法

    就可以找到数量少的那一组 的解药的编号

    这一步最多用9头猪

    注意一定要用数量少的那一组,这样才能使数量至少减半,变成2^9数量级

    (⊙o⊙)…,现在没有猪了,还有一瓶解药,怎么办?

    回到第一步,如果有一头猪死了,代表它要么喝下了两瓶解药,要么没喝解药,说明两瓶解药的二进制位相同

    如果有一头猪没死,说明两瓶解药的二进制位不同

    记录下那些二进制位不同

    异或上第一瓶解药的编号即可得到第二瓶解药的编号

    在这道题里,

    解药相当于y,

    毒药相当于x,

    猪喝下某些药死了相当于询问的位置异或和为 0 或者 x

    猪喝下某些药没死相当于询问的位置异或和为 y 或者 x xor y

    #include<cstdio>
    #include<vector>
    #include<cstring>
    
    using namespace std;
    
    vector<int>V,U;
    
    bool vis[1001];
    
    int main()
    {
        int n,x,y;
        scanf("%d%d%d",&n,&x,&y);
        int siz;
        int tmp; bool tag=false;
        int bit=0;
        int pos;
        int ans=0;
        for(int i=0;i<=9;++i)
        {
            V.clear();
            if(!tag) memset(vis,false,sizeof(vis));
            for(int j=1;j<=n;++j)
                if(j&(1<<i)) V.push_back(j),vis[j]=true;
            siz=V.size();
            if(!siz) continue;
            printf("? %d ",siz);
            for(int j=0;j<siz;++j) printf("%d ",V[j]);
            printf("
    ");
            fflush(stdout);
            scanf("%d",&tmp);
            if(tmp==y || tmp==(x^y)) 
            {
                bit+=1<<i;
                if(!tag) 
                {
                    tag=true; 
                    pos=i;
                    if(siz<n-siz) U=V,ans=1<<i;
                    else 
                    {
                        for(int j=1;j<=n;++j)
                            if(!vis[j]) U.push_back(j);
                    }
                }
            }
        }
        int m=U.size();
        for(int i=0;i<=9;++i)
        {
            if(pos==i) continue;
            V.clear();
            for(int j=0;j<m;++j)
                if(U[j]&(1<<i)) V.push_back(U[j]);
            siz=V.size();
            if(!siz) continue;
            printf("? %d ",siz);
            for(int j=0;j<siz;++j) printf("%d ",V[j]);
            printf("
    ");
            fflush(stdout);
            scanf("%d",&tmp);
            if(tmp==y || tmp==(x^y)) ans+=1<<i;
        }
        printf("! %d %d",min(ans,ans^bit),max(ans,ans^bit));
    }
  • 相关阅读:
    [转]Delphi中进行延时的4种方法
    [转]delphi 删除动态数组的指定元素
    vue-transition-fade
    移动端list布局,左边固定,右边自适应
    移动端弹窗
    多行文字超出省略显示
    jsonp
    barba 页面渲染
    barba.js 优化页面跳转用户体验
    页面返回无刷新
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8442813.html
Copyright © 2011-2022 走看看