题目链接。
分析:
这题是比赛的题,当时没做出来。后来看了一下题解明白了。
首先看一下异或:
对一行(列)改变奇数次,相当于改变了一次,改变偶数次,相当于没改变。
用flag数组来标记最后的结果,即改没改变。
还有一个问题,对于(xi,yi)要改变两次(即相当于没改变),当每次操作时,对所在行改变一次,对所在列改变一次,那么行列的交叉点(xi,yi)也就相当于没改变,符合题意。
还有flag关于异或的问题。
当前的flag只有两个值,即0,1
当0异或1时,结果为1,也就是说要改变;当0异或0时,结果为0,也就是说不要改变;等等等等。
最后一个问题:发现当把标记数组定义为int时是会超时的。但是用unsigned char或者是char却不会。
AC(代码)如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXN 1010 char G[MAXN][MAXN]; unsigned char row[MAXN], col[MAXN], flag[MAXN][MAXN]; int main(){ int n, i, T, q, nCase=0, x, y, j, cnt; scanf("%d", &T); while(T--){ nCase++; cnt = 0; scanf("%d", &n); memset(row, 0, sizeof(row)); memset(col, 0, sizeof(col)); memset(flag, 0, sizeof(flag)); for(i=0; i<n; i++) scanf("%s", G[i]); scanf("%d", &q); while(q--){ scanf("%d %d", &x, &y); x--; y--; row[x] ^= 1; col[y] ^= 1; } for(i=0; i<n; i++){ for(j=0; j<n; j++) flag[i][j] ^= row[i]; for(j=0; j<n; j++) flag[j][i] ^= col[i]; } for(i=0; i<n; i++){ for(j=0; j<n; j++){ if((G[i][j] == 'w' && flag[i][j] == 0) || (G[i][j] == 'b' && flag[i][j] == 1)) cnt++; } } printf("Case #%d: %d\n", nCase, cnt); } return 0; }