在上一回中,小Hi和小Ho趁着便利店打折,买了一大堆零食。当他们结账后,看到便利店门口还有其他的活动。
店主:买了东西还可以参加游戏活动哦,如果能够完成游戏还有额外的奖品。
小Hi和小Ho赶紧凑了过去。
店主放了一块游戏板在店门口,有5行6列格子。左上角为坐标(1,1)。一部分格子是亮着的,另一部分是暗着的。
店主给出初始的状态,参加游戏的人员需要通过按下某些格子,让游戏板上所有的灯都亮起来就可以赢得奖品。
小Ho:这不就是开关灯问题么,看我来解决它!
本题改编自ACMICPC Greater New York 2002 EXTENDED LIGHTS OUT
第1..5行:1个长度为6的字符串,表示该行的格子状态,1表示该格子是亮着的,0表示该格子是暗的。
保证一定存在解,且一定存在暗着的格子。
需要按下的格子数量k,表示按下这k个位置后就可以将整个游戏板所有的格子都点亮。
接下来k行,每行一个坐标(x,y),表示需要按下格子(x,y)。x坐标较小的先输出,若x相同,则先输出y坐标较小的。
样例输入
001111 011111 111111 111110 111100
样例输出
2 1 1 5 6
#include <bits/stdc++.h> using namespace std; char s[5][7]; int a[30][31]; int dx[]={0, 0, 0, 1, -1}; int dy[]={0, 1, -1, 0, 0}; int ok(int x, int y){ return x>=0&&x<5&&y>=0&&y<6; } int swap(int i, int j){ int tmp[31]; memcpy(tmp, a[i], sizeof(tmp)); memcpy(a[i], a[j], sizeof(tmp)); memcpy(a[j], tmp, sizeof(tmp)); } int gauss(int n){ for(int i=0; i<n; i++){ for(int j=i; j<n; j++) if(a[j][i]){ swap(i, j); break; } for(int j=0; j<n; j++) if(j!=i&&a[j][i]){ //消去第j行第i项 for(int k=i; k<=n; k++) a[j][k]^=a[i][k]; } //output(); } } int main(){ for(int i=0; i<5; i++) cin>>s[i]; for(int i=0; i<5; i++) for(int j=0; j<6; j++){ int now=6*i+j; for(int k=0; k<5; k++){ int x=i+dx[k], y=j+dy[k]; if(ok(x, y)){ int nei=6*x+y; a[now][nei]=1; } } a[now][30]=(s[i][j]-‘0‘)^1; } gauss(30); int ans=0; for(int i=0; i<30; i++) ans+=a[i][30]; cout<<ans<<endl; for(int i=0; i<30; i++) if(a[i][30]) cout<<i/6+1<<‘ ‘<<i%6+1<<endl; }
原文:http://www.cnblogs.com/Patt/p/4903135.html