B题:
看到还没有人发这种题解,我就来发一下吧,枚举第一行所有情况,因为只有4个位置,那么第一行的所有情况有(1<<n) - 1 种,那么直接枚举,对于下面三行还是一个简单的遍历,只要这个点的上方是1,那么我就对这个点操作一下,依次进行到第四行,最后我遍历一下第四行看看是否全为0,如何全为0则成功。
#include<bits/stdc++.h>
using namespace std;
int mp[6][6],nmp[6][6];
char mps[6][6];
void change(int x,int y){//操作这个点
mp[x][y] = 1 - mp[x][y];
mp[x + 1][y] = 1 - mp[x + 1][y];
mp[x][y + 1] = 1 - mp[x][y + 1];
mp[x - 1][y] = 1 - mp[x - 1][y];
mp[x][y - 1] = 1 - mp[x][y - 1];
}
int main()
{
for(int i = 1;i <= 4;i++)
for(int j = 1;j <= 4;j++) cin >> mps[i][j];
for(int i = 1;i <= 4;i++)
for(int j = 1;j <= 4;j++){
if(mps[i][j] == '1') mp[i][j] = 1;
else mp[i][j] = 0;
}
memcpy(nmp,mp,sizeof mp);
for(int i = 0;i < (1 << 4);i++){//枚举(1 << n) - 1种情况
int flag = 0;
for(int j = 0;j <= 3;j++){//先对第i种情况的第一行进行操作
if((i >> j) & 1) change(1,4 - j);
}
for(int j = 1;j <= 4;j++){//判断第一行是否为1,是1求对第二行对应位置操作
if(mp[1][j] == 1) change(2,j);
}
for(int j = 1;j <= 4;j++){//同理
if(mp[2][j] == 1) change(3,j);
}
for(int j = 1;j <= 4;j++){//同理
if(mp[3][j] == 1) change(4,j);
}
for(int j = 1;j <= 4;j++){//最后判断最后一行是否合法即可
if(mp[4][j] == 1){
flag = 1;
}
}
if(flag == 0) {
cout << "YES" << endl;
return 0;
}
memcpy(mp,nmp,sizeof nmp);
}
cout << "NO" << endl;
return 0;
}因为此题的n很小,我直接枚举了,如果n是自己定的话,那么就可以写成递归,原理一样。

京公网安备 11010502036488号