题目描述
农夫约翰偶尔会遇到无聊的青少年,他们晚上去他的农场,把奶牛们弄翻。一天早上,他醒来发现事情又发生了——他的 N∗N 头奶牛排列成了一个完美的 N∗N 方阵(1≤N≤10),但他发现其中一些现在已经被弄翻了,而奶牛们比较笨重,没法自己站起来。
幸运的是,农夫约翰用他的拖拉机和叉车上的零件制造了一台出色的机器---“奶牛救星3000”,它可以一次让一大群奶牛站起来,帮助他尽快让所有奶牛重新站起来。他可以将机器应用于他的奶牛方阵中的任何“左上矩形”——一个包含左上角位置奶牛的矩形子矩阵。当他这样做的时候,机器会翻转这个矩形中的每一头牛,让翻倒的奶牛站起来,但不幸的是,也会把原来站起来的奶牛翻倒!换句话说,机器“切换”矩形中每头牛的状态。
农民约翰认为,通过将他的机器多次应用于适当的矩形集合,他最终可以将所有奶牛恢复到它们站起来的状态。请帮助他确定完成此操作所需的机器应用程序的最小次数。
输入格式
输入第一行包含一个正整数N。 接下来N行,每行有N个0或者1,表示每行奶牛的状态,0表示站着的奶牛,1表示倒下的奶牛。
输出格式
输出一行一个整数,表示使用机器让所有奶牛站起来的最小次数。
样例输入
3 001 111 111
样例输出
2
提示
第一次可以对所有奶牛翻转,变成
110
000
000
第二次对第一行的前两个奶牛翻转,变成
000
000
000
代码实现_
#include<bits/stdc++.h>
using namespace std;
char a[15][15];
int n, ans;
void flip(int x, int y) {
for (int i=1;i<=x;i++) {
for (int j=1;j<=y;j++) {
if (a[i][j]=='1') a[i][j] = '0';
else a[i][j] = '1'; // 1变0, 0变1
}
}
} // 把以x,y为右下角的子矩阵翻转
int main() {
scanf("%d", &n);
for (int i=1;i<=n;i++) {
scanf("%s", a[i]+1); // 每次读取一行,从1位置开始保存
}
ans = 0;
// 从右下角开始倒着往前考虑
for (int i=n;i>=1;i--) {
for (int j=n;j>=1;j--) {
if (a[i][j] == '1') {
flip(i,j); // 如果当前位置是1,需要翻转一次
// printf("%d %d\n", i, j);
ans ++;
}
}
}
printf("%d", ans);
return 0;
}