zoukankan      html  css  js  c++  java
  • [CF1451E1] Bitwise Queries (Easy Version)

    Description

    交互题,用不超过 (n+2) 次操作猜出一个长度为 (n) 的数组,每次可以指定两个不同的下标,询问这两个位置的数的 AND 或 OR 或 XOR。

    Solution

    一个直观的思路是先猜出一小部分数,进而通过异或操作得出剩下的。

    猜一个是不行的,猜两个似乎也是不行的。

    考虑猜三个,我们可以用五个“方程”去求解前三个数,至于选取怎样的组合有很多种方案,可以写个暴力程序尝试几次或者手玩一下。

    #include <bits/stdc++.h>
    using namespace std;
    
    void clamp(int &x)
    {
        x = x != 0;
    }
    
    bool check(int a, int b, int c, int u, int v, int x, int y, int z)
    {
        clamp(a);
        clamp(b);
        clamp(c);
        clamp(u);
        clamp(v);
        clamp(x);
        clamp(y);
        clamp(z);
        return u == (a ^ b) && v == (b ^ c) && x == (a | c) && y == (a & b) && z == (b & c);
    }
    
    void solve(int &a, int &b, int &c, int u, int v, int x, int y, int z, int bm)
    {
        for (int ia = 0; ia < 2; ia++)
        {
            for (int ib = 0; ib < 2; ib++)
            {
                for (int ic = 0; ic < 2; ic++)
                {
                    if (check(ia, ib, ic, (u & bm) > 0, (v & bm) > 0, (x & bm) > 0, (y & bm) > 0, (z & bm) > 0))
                    {
                        a += bm * ia;
                        b += bm * ib;
                        c += bm * ic;
                        return;
                    }
                }
            }
        }
    }
    
    int main()
    {
        int u = 0, v = 0, x = 0, y = 0, z = 0, n;
        cin >> n;
        cout << "XOR 1 2 
    XOR 2 3 
    OR 1 3 
    AND 1 2 
    AND 2 3"
             << endl;
        cout.flush();
        cin >> u >> v >> x >> y >> z;
    
        int *a = new int[n + 5];
    
        for (int i = 1; i <= 3; i++)
            a[i] = 0;
    
        for (int i = 1; i < n; i *= 2)
            solve(a[1], a[2], a[3], u, v, x, y, z, i);
    
        for (int i = 4; i <= n; i++)
        {
            cout << "XOR 1 " << i << endl;
            cout.flush();
            cin >> a[i];
            a[i] ^= a[1];
        }
    
        cout << "! ";
        for (int i = 1; i <= n; i++)
            cout << a[i] << " ";
        cout << endl;
    }
    
  • 相关阅读:
    form提交上传图片
    存储过程分页
    表格隔行换色效果
    C#获取本地局域网IP
    sql 拆分字符串并循环取值
    sql日期转换
    HDU 4858
    HDU 1199
    URAL 1306
    Codeforces Round #288 (Div. 2)
  • 原文地址:https://www.cnblogs.com/mollnn/p/14090161.html
Copyright © 2011-2022 走看看