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;
}