2615 修改01矩阵
有一个n*n的01矩阵,每次操作可以选择一个位置改变这个位置元素的值(0变成1,1变成0),
但是这个位置的上下左右四个位置的元素的状态也会发生改变(0变成1,1变成0),问是否可以
通过这个操作,将01矩阵所有元素都变成0,操作次数不限,也可以为0次。
1 1 1
1 0 1
1 1 1在这个数据中,可以使所有元素都变成0的操作方式为:
1 1 1
1 0 1
1 1 11代表对这个位置的元素进行一次操作,0代表没有进行。
输入
第1行:一个整数n表示矩阵的大小为n*n。(1<=n<=10) 第2~n+1行,每行n个正整数,第i行第j个正整数表示01矩阵第i行第j列位置元素的值a[i][j]。 (0<=a[i][j]<=1)输出
如果可以通过上述操作将01矩阵的所有元素变为0,输出"Yes",否则输出"No"。输入样例
3 1 1 1 1 0 1 1 1 1输出样例
Yes
思路:
首行状态确定了整个矩阵的状态也就确定了?没看出来。
题解思路:
(没有对关键做出解释。。。):
n比较小,状态压缩首行每位是否翻转,则后续每行的状态都已确定,
当前行是否翻转需要看上一行当前位置是否为0,翻转结束后看最后一行
是全为0即可。
代码实现:
#include<iostream>
#include<string.h>
#include<math.h>
#include<set>
#include<map>
#include<stdio.h>
#include<algorithm>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int N = 2e5 + 100;
const int M = 4e5 + 100;
int arr[12][12], tmp[12][12];
int xx[5] = {0, 0, 0, 1, -1};
int yy[5] = {0, 1, -1, 0, 0};
void sol (int x, int y, int t[12][12]) {
t[x][y] ^= 1;
for (int i = 1; i <= 4; i++) {
int tx = x + xx[i];
int ty = y + yy[i];
t[tx][ty] ^= 1;
}
}
int main() {
#ifdef MYHOME
freopen ("input.txt", "r", stdin);
#endif
int n, f;
while (cin >> n) {
memset(tmp, 0, sizeof(tmp));
for (int i = 1; i <= n; i++)
for(int j = 1; j <=n ; j++)
cin >> arr[i][j];
for(int i = 0; i < (1 << n); i++) {
f = 0;
for (int j = 1; j <= n; j++)
for(int k = 1; k <= n; k++)
tmp[j][k] = arr[j][k];
for(int j = 0; j < n; j++)
if(i >> j & 1)
sol(1, j + 1, tmp);
for(int j = 2; j <= n; j++)
for(int k = 1; k <= n; k++)
if(tmp[j - 1][k])
sol (j, k, tmp);
for(int j = 1; j <= n; j++)
if(tmp[n][j])
{ f = 1; break; }
if(f == 0) break;
}
if (f == 0)
cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}
THE END;