D. Fixed Point Guessing(构造题)

 

 

 

 

 

 思路:二分。

对于一个区间[l, r],判断在这区间内有多少个数组a元素在区间内,若cnt为奇数,则定点在[l, r]区间内,否则不在。

证明:

假设a[x] = x属于[l, r], 与a[y] = y不属于[l, r]交换,则对cnt没有任何贡献

若a[x] = x属于[l, r], 与a[y] = y属于[l, r]交换,则cnt += 2

若定点在[l, r]区间内,则cnt += 1. 得证

AC代码:

#include <bits/stdc++.h>
using namespace std;
int n, t;
int main(){
    cin >> t;
    while(t--){
        cin >> n;
        int l = 1, r = n;
        while(l < r){
            int mid = l + r >> 1;
            int cnt = 0;
            cout << "? " << l << ' ' << mid << endl;
            for(int i=l;i<=mid;i++){
                int x;
                cin >> x;
                if(x >= l && x <= mid) cnt++;
            }
            if(cnt & 1) r = mid;
            else l = mid + 1;
        }
        cout << "! " << l << endl;
    }
    return 0;
}

 

posted @ 2022-07-06 11:24  聊服一  阅读(46)  评论(0)    收藏  举报