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

浙公网安备 33010602011771号