上次周赛碰到这个题目,居然都没思路,真是不应该啊,起码也应该想到枚举法。
因为题目只允许每一row进行reverse操作,而每两列可以进行交换操作,所以首先把row的变化固定下来,即枚举第一列与第1-m列进行交换,之后逐个检查每一行第一列的状态 与 终态是否一致,不一致的话则该行就一定要进行reverse操作了,这样下来,每次枚举就把row的reverse变化给固定下来,接下来只要枚举 接下来的2-m行互相的列变换即可,只需一个嵌套循环即可,总的循环也只是三重 而n和m仅有100,规模承担的起
一个简单的枚举暴力题 虽然说还是带有一点技巧的,怎么比赛的时候就没想出来呢!!!
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int ma[105][105],tar[105][105],tmp[105][105]; int n,m; void init() { for (int i=1;i<=n;i++) { for (int j=1;j<=m;j++) scanf("%d",&ma[i][j]); } for (int i=1;i<=n;i++) { for (int j=1;j<=m;j++) scanf("%d",&tar[i][j]); } } void cpy(int c) { for (int i=1;i<=m;i++) { for (int j=1;j<=n;j++) { tmp[j][i]=ma[j][i]; } } } void change_col(int a,int b) { for (int i=1;i<=n;i++) { int temp=tmp[i][a]; tmp[i][a]=tmp[i][b]; tmp[i][b]=temp; } } void change_row(int c) { for (int i=1;i<=m;i++) tmp[c][i]^=1; } bool ok(int a,int b) { for (int i=1;i<=n;i++) { if (tar[i][a]!=tmp[i][b]) return false; } return true; } int main() { while (scanf("%d%d",&n,&m)) { if (n==-1) break; init(); bool ans=0; for (int i=1;i<=m;i++) { cpy(i); change_col(1,i); for (int j=1;j<=n;j++) { if (tmp[j][1]!=tar[j][1]) change_row(j); } for (int j=2;j<=m;j++) { for (int k=j;k<=m;k++) { ans=ok(j,k); if (ans) { change_col(j,k); break; } } } if (ans) break; } if (ans) puts("Yes"); else puts("No"); } return 0; }
HDU 3484 Matrix Game 枚举暴力,布布扣,bubuko.com
原文:http://www.cnblogs.com/kkrisen/p/3595377.html