HDOJ 4146 Flip Game

来源:互联网 发布:电脑没有usb端口 编辑:程序博客网 时间:2024/06/05 14:58

超级传送门:

http://acm.hdu.edu.cn/showproblem.php?pid=4146

有一个棋盘,有黑白两色棋子布满棋盘,黑色是b,白色是w。棋盘从左至右编号1~N,从上至下编号1~N,然后执行一系列命令(Xi,Xj),反转第Xi行和第Xj列,可以看出处在(Xi,Xj)这个点上的棋子被反转了两次,所以没变。题目要求输出执行一系列指令后棋盘上剩余的白子数目。

题目数据量 (1 <= N <= 1000, 0 <= Q <= 100000),如果直接用模拟法,每条指令都遍历一下该行和该列并反转,那么很容易TLE。可以用两个数组来记录每行和每列被反转的次数,如果该点所在的行和列的翻转次数之和是偶数,则该点保持原状,否则的话就变反,如此可节约时间,但还是相当暴力。

#include<stdio.h>#include<string.h>int map[1050][1050];int Qa[100010],Qb[100010];int main () {    //freopen("1.txt","r",stdin);    int t,n,q,qa,qb,i,j,k,sum,len;    char temp[1050];    scanf("%d",&t);    for (i=0;i<t;i++) {        memset(map,0,sizeof(map));        memset(Qa,0,sizeof(Qa));        memset(Qb,0,sizeof(Qb));        scanf("%d",&n);        sum = 0;        for (j=1;j<=n;j++) {            scanf("%s",temp);            len = strlen(temp);            for (k=0;k<len;k++) {                if (temp[k]=='b') map[j][k+1] = 0;                else if (temp[k]=='w') map[j][k+1] = 1;            }        }        scanf("%d",&q);        for (j=0;j<q;j++) {            scanf("%d%d",&qa,&qb);            Qa[qa] ++;            Qb[qb] ++;        }        for (j=1;j<=n;j++) {            for (k=1;k<=n;k++) {                if ((Qa[j]+Qb[k])%2==0 && map[j][k]) sum ++;                if ((Qa[j]+Qb[k])%2==1 && !map[j][k]) sum ++;            }        }        printf("Case #%d: %d\n",i+1,sum);    }    return 0;}