Guess Table

Guess Table

经过观察,我们可以构造出一个如下步骤的算法:

  • 询问出网格的一行和一列

  • 询问出剩下的格子

首先考虑后半部分,显然我们直接对全局查询,将该位填充为 \(0\) 判断是否存在即可。

这部分需要用到的询问次数是 \(12^2 = 144\),则第一部分的询问次数最多为 \(56\)。

接下来询问第一部分,我们考虑先问出行再问出列。

增量法,询问每个值都要最多 \(2\) 次。注意可能得到两个不合法,这种情况说明这一段到头了,需要换一端进行增量。这种情况最多会发生 \(1\) 次,总共需要 \(28\) 次。

接下来对于列,我们仍然考虑增量构造,根据上面的理论,需要 \(26\) 次询问。

也就是说,我们完成了本题。

实现时可以进行一些神秘优化减少代码长度和次数。

//Ad astra per aspera
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
int n,m;
char query[20][20],ans[20][20];
bool help_1(vector<char> front_1,vector<char> back_1){
	int new_m=front_1.size()+back_1.size();
	for(int i=1;i<=1;i++){
		for(int j=1;j<=new_m;j++){
			query[i][j]='?';
		}
	}
	int pos2=front_1.size();
	for(int i=0;i<front_1.size();i++){
		query[1][pos2-i]=front_1[i];
	}
	for(int i=0;i<back_1.size();i++){
		query[1][pos2+i+1]=back_1[i];
	}
	cout<<"Query: "<<1<<" "<<new_m<<endl;
	for(int i=1;i<=1;i++){
		for(int j=1;j<=new_m;j++){
			cout<<query[i][j];
		}
		cout<<endl;
	}
	int num;
	cin>>num;
	if(num){
		return true;
	}
	else{
		return false;
	}
} 
bool help_2(vector<char> front_2,vector<char> back_2,vector<char> front_1,vector<char> back_1){
	int new_n=front_2.size()+back_2.size()+1;
	for(int i=1;i<=new_n;i++){
		for(int j=1;j<=m;j++){
			query[i][j]='?';
		}
	}
	int pos=front_2.size()+1;
	for(int i=0;i<front_2.size();i++){
		query[pos-i-1][1]=front_2[i];
	}
	for(int i=0;i<back_2.size();i++){
		query[pos+i+1][1]=back_2[i];
	}
	int pos2=front_1.size();
	for(int i=0;i<front_1.size();i++){
		query[pos][pos2-i]=front_1[i];
	}
	for(int i=0;i<back_1.size();i++){
		query[pos][pos2+i+1]=back_1[i];
	}
	cout<<"Query: "<<new_n<<" "<<m<<endl;
	for(int i=1;i<=new_n;i++){
		for(int j=1;j<=m;j++){
			cout<<query[i][j];
		}
		cout<<endl;
	}
	int num;
	cin>>num;
	if(num){
		return true;
	}
	else{
		return false;
	}
} 
void help_3(vector<char> front_2,vector<char> back_2,vector<char> front_1,vector<char> back_1){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			ans[i][j]='?';
		}
	}
	int pos=front_2.size()+1;
	for(int i=0;i<front_2.size();i++){
		ans[pos-i-1][1]=front_2[i];
	}
	for(int i=0;i<back_2.size();i++){
		ans[pos+i+1][1]=back_2[i];
	}
	int pos2=front_1.size();
	for(int i=0;i<front_1.size();i++){
		ans[pos][pos2-i]=front_1[i];
	}
	for(int i=0;i<back_1.size();i++){
		ans[pos][pos2+i+1]=back_1[i];
	}
} 
bool help_4(){
	cout<<"Query: "<<n<<" "<<m<<endl;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cout<<ans[i][j];
		}
		cout<<endl;
	}
	int num;
	cin>>num;
	if(num){
		return true;
	}
	else{
		return false;
	}
}
int main(){
	cin>>n>>m;
	vector<char> vec_front,vec_back;
	bool flag=true;
	for(int i=1;i<=m;i++){
		if(flag==true){
			vec_front.push_back('0');
			if(!help_1(vec_front,vec_back)){
				vec_front.pop_back();
				vec_front.push_back('1');
				if(!help_1(vec_front,vec_back)){
					vec_front.pop_back();
					flag=false;
				}
			}
		}
		if(flag==false){
			vec_back.push_back('0');
			if(!help_1(vec_front,vec_back)){
				vec_back.pop_back();
				vec_back.push_back('1');
			}
		}
	}
	vector<char> vec_front_2,vec_back_2;
	flag=true;
	for(int i=1;i<n;i++){
		if(flag==true){
			vec_front_2.push_back('0');
			if(!help_2(vec_front_2,vec_back_2,vec_front,vec_back)){
				vec_front_2.pop_back();
				vec_front_2.push_back('1');
				if(!help_2(vec_front_2,vec_back_2,vec_front,vec_back)){
					vec_front_2.pop_back();
					flag=false;
				}
			}
		}
		if(flag==false){
			vec_back_2.push_back('0');
			if(!help_2(vec_front_2,vec_back_2,vec_front,vec_back)){
				vec_back_2.pop_back();
				vec_back_2.push_back('1');
			}
		}
	}
	help_3(vec_front_2,vec_back_2,vec_front,vec_back);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(ans[i][j]=='?'){
				ans[i][j]='0';
				if(!help_4()){
					ans[i][j]='1';
				}
			}
		}
	}
	cout<<"Answer:"<<endl;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cout<<ans[i][j];
		}
		cout<<endl;
	}
	return 0;
}
posted @ 2026-05-15 13:23  Oken喵~  阅读(25)  评论(0)    收藏  举报