acm交互题

1、Dragon Balls


根据勾股定理把所有整数点都给求解出来,然后依次询问,注意数据范围

暴力求解,把每次可能的值都求出来,然后逐个比较。

#include<bits/stdc++.h>
#define int long long int
using namespace std;

int x, n;
typedef pair<int, int> pii;
vector<pii> vet;

signed main(){
    cin >> n;
    while(n -- ){
        cout << 0 <<" " << 0 << endl;
        cout.flush();
        cin >> x;
        vet.clear();
        if(x == 0) continue;
        for(int i = 0; i * i <= x; i++){
            int a = i * i;
            int b = x - a;
            int y = sqrt(b);
            if(y * y == b) vet.push_back({i, y});
        }
        for(vector<pii>::iterator it = vet.begin(); it != vet.end(); it ++){
            pii t = *it;
            if(t.first < 0 || t.first > 1e6 || t.second < 0 || t.second > 1e6) continue;
            cout << t.first <<" " << t.second << endl;
            cout.flush();
            cin >> x;
            if(x == 0) break;
        }
    }
    return 0;
}

2、D. Fixed Point Guessing


题意:给你n个数(n是奇数),交换(n) / 2组不交叉的数,比如刚开始是1,2,3,4,5交换完之后可能是4,2,5,1,3。通过不超过15次询问,找出来那个没有被交换的位置。

在一个区间里面,如果含有没有被交换位置的数,那么这个属于这个区间的数的个数一定是奇数。
因为,如果是区间内的数相互交换,那么贡献值是2,如果是某个数和外边的数交换,贡献值是0.只有当含有不交换的那个数的时候,该区间内的属于这个区间的数的个数才会是奇数。
比较裸的一个二分。

#include<bits/stdc++.h>
using namespace std;

const int N = 1e4 + 10;
int t, n, a[N], cnt, x;

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> t;
    while( t --){
        cin >> n;
        int l = 1, r = n;
        while(l < r){
            int mid = (l + r + 1) >> 1;
            cnt = 0;
            cout << "? " << mid <<" " << r << endl;
            cout.flush();
            for(int i = 1; i <= r - mid + 1; i ++){
                cin >> x;
                if(x >= mid && x <=r) cnt ++;
            }
            if(cnt % 2 != 0) l = mid;
            else r = mid - 1;
        }
        cout <<"! " << l << endl;
    }
    return 0;
}

3、I. Interactive Treasure Hunt


题意:在一个最大16*16的网格里,有两个点有宝藏,通过不超过七次询问,找出宝藏的位置。询问有两种,①scan x y:输出俩宝藏到点(x,y)的曼哈顿距离和;②dig x y:询问点(x,y)是不是宝藏点。

思路:先scan(1,1),scan(n,1)。求出来俩距离d1,d2。然后整理算出来sx = x1 + x2, sy = y1 + y2。下一步,scan(sx/2,1),scan(1,sy/2)。根据这四个式子,可以算出来x1,x2,y1,y2。但不确定y1,y2和x1,x2的对应关系,所以询问一次,看哪个是符合条件的。

#include <bits/stdc++.h>
using namespace std;
int t,  x,  y,d1, d2, d3,d4, n, m, d5;


signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> t;
    while(t --){
        cin >> n >> m;
        int cnt = 4;
        cout << "SCAN " << 1 <<" " << 1 << endl;
        cout.flush();
        cin >> d1;
        cout << "SCAN " << n <<" " << 1 << endl;
        cout.flush();
        cin >> d2;
        int sx = (d1 - d2 + 2 * n + 2) / 2 ;
        int sy = (d2 + d1 + 6 - 2 * n) / 2;
        cout << "SCAN " << sx / 2 <<" " << 1 << endl;
        cout.flush();
        cin >> d3;
        cout << "SCAN " << 1 <<" " << sy / 2 << endl;
        cout.flush();
        cin >> d4;
        int nx = (sx - (d3 - sy + 2))/ 2;
        int mx = (sx + d3 - sy + 2) / 2;
        int ny = (sy - (d4 - sx + 2))/ 2;
        int my = (sy + (d4 - sx + 2)) / 2;
        cout <<"DIG " << nx <<" " << ny << endl;
        cout.flush();
        cin >> x;
        if(x == 1){
            cout <<"DIG " << mx <<" " << my << endl;
            cin >> x;
        }
        else{
            cout <<"DIG " << nx <<" " << my << endl;
            cin >> x;
            cout <<"DIG " << mx <<" " << ny << endl;
            cin >> y;
        }
    }
    return 0;
}

posted @ 2022-09-12 15:15  风归去  阅读(241)  评论(0编辑  收藏  举报