Codeforces\ Round\ 930(C.Bitwise Operation Wizard)

C o d e f o r c e s   R o u n d   930 ( C . B i t w i s e O p e r a t i o n W i z a r d ) \Huge{Codeforces\ Round\ 930(C.Bitwise Operation Wizard)} Codeforces Round 930(C.BitwiseOperationWizard)

文章目录


题目链接:[B.Bitwise Operation Wizard](Problem - C - Codeforces)

本题是一道交互题,好久没做交互题了,记录一下。

题意

给出一个长度为 n n n ( 0 , n − 1 ) (0,n-1) (0,n1)的排列组合序列,要求找到下标 i , j i,j i,j,使得 p i   X O R   p j {\color{Red} p_i~XOR~p_j} pi XOR pj的值最大。

其中,题目给出不超过 3 n 3n 3n次查询:

查询格式为:? a b c d ( 0 ≤ a , b , c , d < n 0 \le a,b,c,d < n 0a,b,c,d<n)

返回为: x = ( p a ∣ p b ) x = (p_a \mid p_b) x=(papb) y = ( p c ∣ p d ) y = (p_c \mid p_d) y=(pcpd),返回字符 ′ < ′ , ′ > ′ , ′ = ′ '<','>','=' <,>,=分别对应 x < y , x > y , x = y x<y,x>y,x=y x<y,x>y,x=y三种情况。

最后输出结果:! i j

思路

  1. 首先考虑结果,易知:当 p j p_j pj n − 1 n-1 n1时, p i p_i pi ! ( p j ) !(p_j) !(pj)时, p i   X O R   p j {\color{Red} p_i~XOR~p_j} pi XOR pj的值最大。
  2. 所以我们可以用? a a b b,在 n n n次内找出最大值的下标,即 p j p_j pj j j j
  3. 然后我们用? j mx j i,在 n n n次内找出所有与 p j p_j pj进行或运算之后的最大值下标
  4. 然后我们枚举所有的下标,找出最小的 p i p_i pi,即为所求。
  5. 易证:所有与 p j p_j pj进行或运算后的结果相等的数字中,最小的数与 p j p_j pj进行 X O R XOR XOR运算结果最大

注意

在交互题中,交互过程中的输入输出需要刷新输入输出,c/c++通常使用fflush(stdout)cout.flush()

标程

char query(int a, int b, int c, int d) {
    char ch;
    cout << "? " << a <<' '<< b <<' '<< c <<' '<< d << endl;
    cout.flush();
    cin >> ch;
    cout.flush();

    return ch;
}

void Solved() {
    int n; cin >> n;
    int res1 = 0, res2 = 0, mx = 0;
    vector<int> a;

    for(int i = 1; i < n; i ++ ) {
        char ch = query(res1, res1, i, i);
        if(ch == '<') res1 = i;
    }
    
    a.push_back(0);
    for(int i = 1; i < n; i ++ ) {
        char ch = query(mx, res1, i, res1);
        if(ch == '<') {
            mx = i; a.clear(); a.push_back(i);
        }
        if(ch == '=') a.push_back(i);
    }

    res2 = a.front();
    for(int i = 1; i < a.size(); i ++ ) {
        char ch = query(res2, res2, a[i], a[i]);
        if(ch == '>') res2 = a[i];
    }
    
    cout << "! " << res1 << ' ' << res2 << endl;
    cout.flush();
}
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值