CF1666I Interactive Treasure Hunt

Luogu 链接
CodeForces 链接
Virtual Judge 链接

题意

本题为 IO 交互题,请注意刷新缓冲区。


题目描述

有一个 \(n\times m\) 的网格,其中有两个不同的格子有宝藏,你可以进行以下两种操作:

  • \(\texttt{DIG}\ r\ c\):交互器将告诉你格子 \((r,c)\) 里是否有宝藏。
  • \(\texttt{SCAN}\ r\ c\):交互器将告诉你格子 \((r,c)\) 到两个宝藏所在格子的曼哈顿距离之和。\((r_1,c_1)\)\((r_2,c_2)\) 的曼哈顿距离被定义为 \(\lvert r_1-r_2\rvert+\lvert c_1-c_2\rvert\)

你最多只能执行这些操作共 \(7\) 次,并且对于每个宝藏的位置你需要至少 \(\texttt{DIG}\) 一次


交互格式

多测,第一行一个整数 \(T\)\(1\le T\le100\)),代表有 \(T\) 组数据。

每组数据的第一行有两个整数 \(n\)\(m\)\(1\le n,m\le10^6\))。

接下来,你的程序可以进行两种查询:

  • \(\texttt{DIG}\ r\ c\):若这个格子有宝藏,且尚未被 \(\texttt{DIG}\),则交互器会返回 \(1\);否则返回 \(0\)
  • \(\texttt{SCAN}\ r\ c\):见题目描述

在找到两个宝藏后(即有两次 \(\texttt{DIG}\) 操作结果为 \(1\)),你需要立即结束这组数据(读入下组数据或结束程序)。

思路

我们设第一个宝藏的坐标为 \((x_1,y_1)\),第二个宝藏的坐标为 \((x_2,y_2)\),并且 \(x_1\le x_2\)

显然,有四个未知数,所以我们至少要 \(\texttt{SCAN}\) 四次才能得出 \(x_1,x_2,y_1,y_2\) 的值。

但是 \(y_1\)\(y_2\) 的值是可以交换的,所以我们先要 \(\texttt{DIG}\ x_1\ y_1\),若返回值为 \(1\),则继续 \(\texttt{DIG}\ x_2\ y_2\);否则 \(\texttt{DIG}\ x_1\ y_2\)\(\texttt{DIG}\ x_2\ y_1\)

因此,我们至多只需要 \(4\) 次操作就可以找到两个宝藏的位置可以通过此题。

接下来,我们继续讨论如何求出 \(x_1,x_2,y_1,y_2\) 的值:

  • 第一步:令 \(s_1=\texttt{SCAN}\ 1\ 1\),则有 \((x_1+x_2)+(y_1+y_2)=s_1+4\)
  • 第二步:令 \(s_2=\texttt{SCAN}\ 1\ m\),则有 \((x_1+x_2)-(y_1+y_2)=s_2-2m+2\)

通过前两步,我们可以计算出 \(\displaystyle sum_x=x_1+x_2=\frac{s_1+s_2-2m+6}{2}\)\(\displaystyle sum_y=y_1+y_2=\frac{s_1-s_2+2m+2}{2}\)

而要算出 \(delta_x=x_2-x_1\)\(delta_y=\lvert y_1-y_2\rvert\),我们可以进行如下操作:

  • 第三步:令 \(\displaystyle s_3=\texttt{SCAN}\ \lfloor\frac{sum_x}{2}\rfloor\ 1\),则有 \((x_2-x_1)+(y_1+y_2)=s_3+2\)
  • 第四步:令 \(\displaystyle s_4=\texttt{SCAN}\ 1\ \lfloor\frac{sum_y}{2}\rfloor\),则有 \((x_1+x_2)+\lvert y_1-y_2\rvert=s_4+2\)

通过上述两步,我们可以计算出 \(delta_x=s_3+2-sum_y,delta_y=s_4+2-sum_x\)

计算出 \(sum_x,sum_y,delta_x,delta_y\) 后,我们利用小学数学知识就可以计算出 \(x_1,x_2,y_1,y_2\) 了,此处不再赘述。

程序

AC 记录

#include<cstdlib>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdio>
#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<iomanip>
#include<string>
#include<stack>
#include<random>
#include<utility>
#define re register
#define ll long long
#define ull unsigned long long
#define vl __int128
#define ld long double
#define LL 2e18
#define INT 1e9
#define INF 0x3f3f3f3f
#define MP make_pair
#define pb push_back
#define lb(x) (x&(-x))
#ifdef __linux__
#define gc getchar_unlocked
#define pc putchar_unlocked
#else
#define gc _getchar_nolock
#define pc _putchar_nolock
#endif
int T=1;
using namespace std;
pair<int*,int*> pair_int;pair<ll*,ll*> pair_ll;pair<ull*,ull*> pair_ull;pair<double*,double*> pair_double;pair<ld*,ld*> pair_ld;pair<char*,char*> pair_char;pair<bool*,bool*> pair_bool;
inline bool blank(const char x){return !(x^32)||!(x^10)||!(x^13)||!(x^9);}
template<typename Tp>inline void read(Tp &x){x=0;bool z=true;char a=gc();for(;!isdigit(a);a=gc())if(a=='-')z=false;for(;isdigit(a);a=gc())x=(x<<1)+(x<<3)+(a^48);x=(z?x:~x+1);}
inline void read(double &x){x=0.0;bool z=true;double y=0.1;char a=gc();for(;!isdigit(a);a=gc())if(a=='-')z=false;for(;isdigit(a);a=gc())x=x*10+(a^48);if(a!='.')return x=z?x:-x,void();for(a=gc();isdigit(a);a=gc(),y/=10)x+=y*(a^48);x=(z?x:-x);}
inline void read(ld &x){x=0.0;bool z=true;ld y=0.1;char a=gc();for(;!isdigit(a);a=gc())if(a=='-')z=false;for(;isdigit(a);a=gc())x=x*10+(a^48);if(a!='.')return x=z?x:-x,void();for(a=gc();isdigit(a);a=gc(),y/=10)x+=y*(a^48);x=(z?x:-x);}
inline void read(char &x){for(x=gc();blank(x)&&(x^-1);x=gc());}
inline void read(char *x){char a=gc();for(;blank(a)&&(a^-1);a=gc());for(;!blank(a)&&(a^-1);a=gc())*x++=a;*x=0;}
inline void read(string &x){x="";char a=gc();for(;blank(a)&&(a^-1);a=gc());for(;!blank(a)&&(a^-1);a=gc())x+=a;}
template<typename T>inline void read(pair<T*,T*> p){T *begin,*end,*i;begin=p.first,end=p.second;if(begin<end)for(i=begin;i<end;++i)read(*i);else for(i=begin-1;i>=end;--i)read(*i);}
template<typename T,typename ...Tp>inline void read(T &x,Tp &...y){read(x),read(y...);}
template<typename Tp>inline void write(Tp x){if(!x)return pc(48),void();if(x<0)pc('-'),x=~x+1;int len=0;char tmp[64];for(;x;x/=10)tmp[++len]=x%10+48;while(len)pc(tmp[len--]);}
inline void write(const double x){int a=6;double b=x,c=b;if(b<0)pc('-'),b=-b,c=-c;double y=5*powl(10,-a-1);b+=y,c+=y;int len=0;char tmp[64];if(b<1)pc(48);else for(;b>=1;b/=10)tmp[++len]=floor(b)-floor(b/10)*10+48;while(len)pc(tmp[len--]);pc('.');for(c*=10;a;a--,c*=10)pc(floor(c)-floor(c/10)*10+48);}
inline void write(const ld x){int a=6;ld b=x,c=b;if(b<0)pc('-'),b=-b,c=-c;ld y=5*powl(10,-a-1);b+=y,c+=y;int len=0;char tmp[64];if(b<1)pc(48);else for(;b>=1;b/=10)tmp[++len]=floor(b)-floor(b/10)*10+48;while(len)pc(tmp[len--]);pc('.');for(c*=10;a;a--,c*=10)pc(floor(c)-floor(c/10)*10+48);}
inline void write(const pair<int,double>x){int a=x.first;if(a<7){double b=x.second,c=b;if(b<0)pc('-'),b=-b,c=-c;double y=5*powl(10,-a-1);b+=y,c+=y;int len=0;char tmp[64];if(b<1)pc(48);else for(;b>=1;b/=10)tmp[++len]=floor(b)-floor(b/10)*10+48;while(len)pc(tmp[len--]);a&&(pc('.'));for(c*=10;a;a--,c*=10)pc(floor(c)-floor(c/10)*10+48);}else printf("%.*lf",a,x.second);}
inline void write(const pair<int,ld>x){int a=x.first;if(a<7){ld b=x.second,c=b;if(b<0)pc('-'),b=-b,c=-c;ld y=5*powl(10,-a-1);b+=y,c+=y;int len=0;char tmp[64];if(b<1)pc(48);else for(;b>=1;b/=10)tmp[++len]=floor(b)-floor(b/10)*10+48;while(len)pc(tmp[len--]);a&&(pc('.'));for(c*=10;a;a--,c*=10)pc(floor(c)-floor(c/10)*10+48);}else printf("%.*Lf",a,x.second);}
inline void write(const char x){pc(x);}
inline void write(const bool x){pc(x?49:48);}
inline void write(char *x){fputs(x,stdout);}
inline void write(const char *x){fputs(x,stdout);}
inline void write(const string &x){fputs(x.c_str(),stdout);}
template<typename T>inline void write(pair<T*,T*> p){T *begin,*end,*i;begin=p.first,end=p.second;for(i=begin;i<end;++i)write(*i),write(' ');}
template<typename T>inline void write(pair<pair<T*,T*>,char> p){T *begin,*end,*i;begin=p.first.first,end=p.first.second;char c=p.second;for(i=begin;i<end;++i)write(*i),write(c);}
template<typename T,typename ...Tp> inline void write(T x,Tp ...y){write(x),write(y...);}
template<typename T>inline void init(T *begin,T *end,const T& val=T()){T* i;for(i=begin;i<end;++i)*i=val;}
template<typename T>inline T max(T *begin,T *end){T *ans,*i;for(i=begin;i<end;++i)if(i==begin||*ans<*i)ans=i;return *ans;}
template<typename T>inline T min(T *begin,T *end){T *ans,*i;for(i=begin;i<end;++i)if(i==begin||*i<*ans)ans=i;return *ans;}
template<typename T>inline T calc_sum(T *begin,T *end,const T& val=T()){T ans=val,*i;for(i=begin;i<end;++i)ans+=*i;return ans;}
template<typename T>inline bool is_equal(T *begin,T *end,const T& val=T()){T *i;for(i=begin;i<end;++i)if(*i!=val)return false;return true;}
template<typename T>inline T qp(T x,T y){T ans=1;while(y){if(y&1)ans=ans*x;x=x*x;y>>=1;}return ans;}
template<typename T>inline T qp(T x,T y,T z){T ans=1;while(y){if(y&1)ans=ans*x%z;x=x*x%z;y>>=1;}return ans;}

ll mod=0;
const int MAXN=0;
const int N=MAXN+10;
//#define DEBUG
//#define more_text

int t,n,m;

int s1,s2,s3,s4,sx,sy,dx,dy,ans;

void SOLVE(int _){
	cin>>t;
	while(t--){
		cin>>n>>m;
		
		cout<<"SCAN 1 1"<<endl;cin>>s1;
		cout<<"SCAN 1 "<<m<<endl;cin>>s2;
		sx=(s1+s2-2*m+6)/2,sy=(s1-s2+2*m+2)/2;
		
		cout<<"SCAN "<<sx/2<<" 1"<<endl;cin>>s3;
		cout<<"SCAN 1 "<<sy/2<<endl;cin>>s4;
		dx=s3+2-sy,dy=s4+2-sx;
		
		cout<<"DIG "<<(sx-dx)/2<<" "<<(sy-dy)/2<<endl;cin>>ans;
		if(ans==1)cout<<"DIG "<<(sx+dx)/2<<" "<<(sy+dy)/2<<endl,cin>>ans;
		else{
			cout<<"DIG "<<(sx-dx)/2<<" "<<(sy+dy)/2<<endl;cin>>ans;
			cout<<"DIG "<<(sx+dx)/2<<" "<<(sy-dy)/2<<endl;cin>>ans;
		}
	}
}
/*
Input:

Output:

Outline:

*/
int main(){
	#ifdef DEBUG
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
	#endif
	#ifdef more_text
	read(T);
	#endif 
	for(int i=1;i<=T;++i)SOLVE(i);
	#ifdef DEBUG
	fclose(stdin);fclose(stdout);
	#endif
	return 0;
}
posted @ 2025-03-10 18:47  LXcjh4998  阅读(22)  评论(0)    收藏  举报