zoukankan      html  css  js  c++  java
  • CodeForces1617D2 Too Many Impostors (hard version)

    题目链接

    题目大意

      有n个玩家,n是3的倍数,有k个冒名顶替者,保证\(\frac{n}{3} < k < \frac{2n}{3}\),每次可以询问3个玩家中冒名顶替者的数量是否大于一半,最多询问n+6次,问冒名顶替者的数量和编号。

    解题思路

      3个一组的询问,因为k的数量限制,必定至少有一组0和一组1,然后我们从两组中各挑两个人,进行四次询问即可找出一个冒名顶替者,一个船员,具体看代码注释。一共消耗\(\frac{n}{3} + 4\)次询问。
      把之前3个一组的询问结果保存下来,如果结果是1,就拿冒名顶替者问12,23两组即可确定3人身份,结果是0类似,具体看代码。一共消耗\(\frac{2n}{3}\)次询问。

    代码

    const int maxn = 2e5+10;                                                               
    const int maxm = 2e6+10;
    struct TRP {
        int a[3];
    };
    TRP t0, t1;
    int ask(int a, int b, int c) {
        printf("? %d %d %d\n", a, b, c);
        //cout << endl;
        fflush(stdout);
        int x; scanf("%d", &x);
        return x;
    }
    vector<TRP> res[2];
    int main() { 
        int __; cin >> __;
        while(__--) {
            int n; scanf("%d", &n);
            res[0].clear(), res[1].clear();
            for (int i = 1; i<=n; i+=3) {
                int x = ask(i, i+1, i+2);
                if (x) t1 = {i, i+1, i+2};
                else t0 = {i, i+1, i+2}; 
                res[x].push_back({i, i+1, i+2});
            }
            int f0, f1, res1, res2, cnt = 0;
            cnt += (res1=ask(t0.a[0], t1.a[0], t1.a[1]));
            cnt += (res2=ask(t0.a[1], t1.a[0], t1.a[1]));
            /*
            00 11 - 1 1 0 0
            00 10 - 0 0 0 0
            01 11 - 1 1 1 1
            01 10 - 0 1 1 0
            */
            cnt += ask(t1.a[0], t0.a[0], t0.a[1]);
            cnt += ask(t1.a[1], t0.a[0], t0.a[1]);        
            if (cnt==0) f0 = t0.a[0], f1 = t1.a[2];
            else if (cnt==4) f0 = t0.a[2], f1 = t1.a[0];
            else {
                if (res1+res2==2) f0 = t0.a[0], f1 = t1.a[0];
                else f0 = t0.a[2], f1 = t1.a[2];
            }
            set<int> ans;
            ans.insert(f0);
            for (auto v : res[0]) {
                int x = ask(f1, v.a[0], v.a[1]);
                int y = ask(f1, v.a[1], v.a[2]);
                if (x+y==0) {
                    ans.insert(v.a[0]);
                    ans.insert(v.a[1]);
                    ans.insert(v.a[2]);
                }
                else if (x+y==2) {
                    ans.insert(v.a[0]);
                    ans.insert(v.a[2]);
                }
                else if (x) {
                    ans.insert(v.a[1]);
                    ans.insert(v.a[2]);
                }
                else {
                    ans.insert(v.a[0]);
                    ans.insert(v.a[1]);
                }
            }
            for (auto v : res[1]) {
                int x = ask(f0, v.a[0], v.a[1]);
                int y = ask(f0, v.a[1], v.a[2]);
                if (x+y==2) continue;
                if (x==1) ans.insert(v.a[2]);
                else if (y==1) ans.insert(v.a[0]);
                else ans.insert(v.a[1]);
            }
            printf("! %d", (int)ans.size());
            for (auto v : ans) printf(" %d", v);
            putchar('\n');
            fflush(stdout);
        }
        return 0;   
    }
    
  • 相关阅读:
    字符串加密
    接口实例
    RecyclerView添加Hearder
    基于Vue实现图片在指定区域内移动
    Tinymce 编辑器添加自定义图片管理插件
    LocalStorage和sessionStorage之间的区别
    javascript之url转义escape()、encodeURI()和decodeURI(),ifram父子传参参数有中文时出现乱码
    Js实现简单的音频播放
    通用CSS命名规范
    Hbuilder常用功能汇总
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/15703107.html
Copyright © 2011-2022 走看看