题目描述

有这样一种魔板:它是一个长方形的面板,被划分成n行m列的n*m个方格。每个方格内有一个小灯泡,灯泡的状态有两种(亮或暗)。我们可以通过若干操作使魔板从一个状态改变为另一个状态。操作的方式有两种:

(1)任选一行,改变该行中所有灯泡的状态,即亮的变暗、暗的变亮;

(2)任选两列,交换其位置。

当然并不是任意的两种状态都可以通过若干操作来实现互相转化的。

你的任务就是根据给定两个魔板状态,判断两个状态能否互相转化。

输入输出格式

输入格式:

文件中包含多组数据。第一行一个整数k,表示有k组数据。

每组数据的第一行两个整数n和m。(0<n,m≤100)

以下的n行描述第一个魔板。每行有m个数字(0或1),中间用空格分隔。若第x行的第y个数字为0,则表示魔板的第x行y列的灯泡为“亮”;否则为“暗”。

然后的n行描述第二个魔板。数据格式同上。

任意两组数据间没有空行。

输出格式:

共k行,依次描述每一组数据的结果。

若两个魔板可以相互转化,则输出YES,否则输出NO。(注意:请使用大写字母)

输入输出样例

输入样例#1:

2
3 4
0 1 0 1
1 0 0 1
0 0 0 0
0 1 0 1
1 1 0 0
0 0 0 0
2 2
0 0
0 1
1 1
1 1
输出样例#1:

YES
NO

Solution:

  本题其实没有想象的那么难(主要是我开始受到刚做的另一道叫魔板的题目影响,下意识的想怎么去判重存状态去了,结果感觉不可做),实际上直接暴力模拟就可以了。

  首先可以确定的是无论怎么操作,每一行的$1$的个数都只有两种情况(要么是本来的$1$的个数,要么是$0$的个数),所以操作$1$对于每行来说最多进行一次,当行中的$0,1$都确定不变后,那么要使初始状态$st$变换到目标状态$ed$就是操作$2$了。

  于是一个很简单的思路就出来了:

  1、先判断$st$的每行$1$的个数是否可以变到$ed$中的每行$1$的个数,若不行直接输出$NO$,可以变换再枚举。

  2、首先枚举$st$的每一列来做为转移时中间状态的第$1$列,通过操作$1$使得其和目标状态的第$1$列相同,之后就只需用到操作$2$,依次枚举剩下的列中和目标状态第$2$列、第$3$列…一直往下(记得当两列相同后,要在中间状态中通过操作$2$移动该列到匹配的位置,否则往后枚举可能会出现列重复使用的情况),当某列无法和目标状态匹配时,直接跳出循环,说明该中间状态不行。

  具体实现,详见代码。

代码:

#include<bits/stdc++.h>
#define il inline
#define ll long long
using namespace std;
const int N=;
int st[N][N],ed[N][N],tmp[N][N],n,m,k,hang1[N],hang2[N];
bool vis[N],f,hang[N],lie[N];
il int gi(){
int a=;char x=getchar();bool f=;
while((x<''||x>'')&&x!='-')x=getchar();
if(x=='-')x=getchar(),f=;
while(x>=''&&x<='')a=a*+x-,x=getchar();
return f?-a:a;
}
il void change1(int x[][N],int k){
for(int i=;i<=m;i++)x[k][i]=-x[k][i];
}
il void change2(int x[][N],int s,int t){
for(int i=;i<=n;i++)swap(x[i][s],x[i][t]);
}
il bool check(int s[][N],int t[][N],int l1,int l2){
for(int i=;i<=n;i++)
if(s[i][l1]!=t[i][l2])return ;
return ;
}
il void init(){
n=gi(),m=gi();f=;
memset(hang1,,sizeof(hang1));
memset(hang2,,sizeof(hang2));
for(int i=;i<=n;i++)
for(int j=;j<=m;j++){
st[i][j]=gi();
if(st[i][j]==)hang1[i]++;
}
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
ed[i][j]=gi();
if(ed[i][j]==)hang2[i]++;
}
if(hang1[i]!=hang2[i]&&hang1[i]!=m-hang2[i])f=;
}
if(f){puts("NO");return;}
for(int p=;p<=m;p++){
memcpy(tmp,st,sizeof(st));
change2(tmp,,p);
for(int i=;i<=n;i++)
if(tmp[i][]!=ed[i][])change1(tmp,i);
for(int i=;i<=m;i++){
f=;
for(int j=i;j<=m;j++)
if(check(tmp,ed,j,i)){change2(tmp,i,j);f=;break;}
if(!f)break;
}
if(f)break;
}
if(f){puts("YES");return;}
puts("NO");
}
int main(){
k=gi();
while(k--){
init();
}
return ;
}

P1275 魔板的更多相关文章

  1. 洛谷P1275 魔板

    P1275 魔板 题目描述 有这样一种魔板:它是一个长方形的面板,被划分成n行m列的n*m个方格.每个方格内有一个小灯泡,灯泡的状态有两种(亮或暗).我们可以通过若干操作使魔板从一个状态改变为另一个状 ...

  2. 洛谷 P1275 魔板

    P1275 魔板 题目描述 有这样一种魔板:它是一个长方形的面板,被划分成n行m列的n*m个方格.每个方格内有一个小灯泡,灯泡的状态有两种(亮或暗).我们可以通过若干操作使魔板从一个状态改变为另一个状 ...

  3. 【洛谷】P1275 魔板(暴力&思维)

    题目描述 有这样一种魔板:它是一个长方形的面板,被划分成n行m列的n*m个方格.每个方格内有一个小灯泡,灯泡的状态有两种(亮或暗).我们可以通过若干操作使魔板从一个状态改变为另一个状态.操作的方式有两 ...

  4. 【题解】魔板—洛谷P1275。

    话说好久没更博了. 最近学了好多知识懒的加进来了. 有幸认识一位大佬. 让我有了继续更博的兴趣. 但这是一个旧的题解. 我在某谷上早就发过的. 拿过来直接用就当回归了吧. 其实这道题有一个特别关键的思 ...

  5. Sicily 1051: 魔板(BFS+排重)

    相对1150题来说,这道题的N可能超过10,所以需要进行排重,即相同状态的魔板不要重复压倒队列里,这里我用map储存操作过的状态,也可以用康托编码来储存状态,这样时间缩短为0.03秒.关于康托展开可以 ...

  6. Sicily 1150: 简单魔板(BFS)

    此题可以使用BFS进行解答,使用8位的十进制数来储存魔板的状态,用BFS进行搜索即可 #include <bits/stdc++.h> using namespace std; int o ...

  7. hdu.1430.魔板(bfs + 康托展开)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  8. HDU 1430 魔板(康托展开+BFS+预处理)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  9. [HDU 1430] 魔板

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

随机推荐

  1. 【实现高可效的代理模式-Squid】

    普通正向代理 首先安装squid代理软件包: 端口控制 在squid server端作端口访问控制,把默认的3128端口改为1000端口 同时把squid服务代理端口添加到selinux安全子系统的允 ...

  2. 【转载】在C#中主线程和子线程如何实现互相传递数据

    引用:https://blog.csdn.net/shuaihj/article/details/41316731 一.不带参数创建Thread using System; using System. ...

  3. Angular : 响应式编程, 组件间通信, 表单

    Angular 响应式编程相关 ------------------------------------------------------------------------------------ ...

  4. YII2 不通过composer安装Ueditor编辑器

    今天用composer安装Ueditor,一直下载失败,不知道为什么,所以就手动安装了一下.记录一下安装步骤 GitHub地址 https://github.com/BigKuCha/yii2-ued ...

  5. 05 redis(进阶)

    redis 阶段一.认识redis 1.什么是redis Redis是由意大利人Salvatore Sanfilippo(网名:antirez)开发的一款内存高速缓存数据库.Redis全称为:Remo ...

  6. 怎么实现hibernate悲观锁和乐观锁?

    隔离级别的安全控制是整体一个大的方面,而锁机制更加的灵活,它执行的粒度可以很小,可以在一个事务中存在. Hibernate悲观锁是依靠底层数据库的锁机制实现,在查询query.setLockMode( ...

  7. 联想ThinkPad S3-S440虚拟机安装,ubuntu安装,Hadoop(2.7.1)详解及WordCount运行,spark集群搭建

    下载ubuntu操作系统版本 ubuntu-14.10-desktop-amd64.iso(64位) 安装过程出现错误: This kernel requires an X86-64 CPU,but ...

  8. CSS3实现3d菜单翻转

    transform-style:flat | preserve-3d: 3d透视属性.针对子元素如何在3d空间相对其父元素渲染,这个属性声明在父元素上,并且他的子元素使用了transform才会有效. ...

  9. 15 GIL 全局解释器锁 C语言解决 top ps

    1.GIL 全局解释器锁:保证同一时刻只有一个线程在运行. 什么是全局解释器锁GIL(Global Interpreter Lock) Python代码的执行由Python 虚拟机(也叫解释器主循环, ...

  10. Android PopupWindow 疑难杂症之宽度WRAP_CONTENT

    一直以来都觉得 Android 中的 PopupWindow 不好用.主要有以下两点:1.宽度不好控制2.位置不好控制 今天单说第1点. 由于应用有好几种国家的语言,加上各设备宣染效果不完全一样,对p ...