[关闭]
@ysner 2018-05-05T17:06:16.000000Z 字数 996 阅读 2060

Luogu1275魔板

搜索 bitset


题面

有这样一种魔板:它是一个长方形的面板,被划分成列的个方格。每个方格内有一个小灯泡,灯泡的状态有两种(亮或暗)。我们可以通过若干操作使魔板从一个状态改变为另一个状态。操作的方式有两种:
(1)任选一行,改变该行中所有灯泡的状态,即亮的变暗、暗的变亮;
(2)任选两列,交换其位置。
你的任务就是根据给定两个魔板状态,判断两个状态能否互相转化。

解析

首先一眼看出个性质:每行亮的灯泡数只可能有两种或一种。
然而这并没有什么卵用
正经一点,这题状态只有走起。
然后我由于列可任意交换,我们可以把列按字典序排序。
再枚举一下看有没有列能成为目标状态第一列即可。
在判定过程中,如果一行数字不同就翻转,到最后再排序,如果后面的列能一一对应就,否则继续。
核心思想就是在模拟时,你只能把一行翻转一次,否则为后面翻转时会改变前面的

  1. int k,n,m,ans;
  2. bitset<105>a[105],b[105],c;
  3. il bool cmp(bitset<105>x,bitset<105>y)
  4. {
  5. fp(i,1,n) if(x[i]^y[i]) return x[i]<y[i];
  6. return 0;
  7. }
  8. int main()
  9. {
  10. //freopen("panel.in","r",stdin);
  11. //freopen("panel.out","w",stdout);
  12. k=gi();
  13. while(k--)
  14. {
  15. n=gi();m=gi();ans=0;
  16. fp(i,1,m) a[i].reset(),b[i].reset();
  17. fp(i,1,n) fp(j,1,m) a[j][i]=gi();
  18. fp(i,1,n) fp(j,1,m) b[j][i]=gi();
  19. sort(a+1,a+1+m,cmp);sort(b+1,b+1+m,cmp);
  20. fp(i,1,m)
  21. {
  22. c=a[i]^b[1];
  23. fp(j,1,m) a[j]^=c;
  24. sort(a+1,a+1+m,cmp);
  25. re int flag=1;
  26. fp(j,1,m) if(a[j]!=b[j]) {flag=0;break;}
  27. if(flag) {ans=1;break;}
  28. fp(j,1,m) a[j]^=c;
  29. sort(a+1,a+1+m,cmp);
  30. }
  31. puts(ans?"YES":"NO");
  32. }
  33. fclose(stdin);
  34. fclose(stdout);
  35. return 0;
  36. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注