P1275 魔板

题目描述

有这样一种魔板:它是一个长方形的面板,被划分成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$移动该列到匹配的位置,否则往后枚举可能会出现列重复使用的情况),当某列无法和目标状态匹配时,直接跳出循环,说明该中间状态不行。

  具体实现,详见代码。

代码:

 1 #include<bits/stdc++.h>
 2 #define il inline
 3 #define ll long long
 4 using namespace std;
 5 const int N=105;
 6 int st[N][N],ed[N][N],tmp[N][N],n,m,k,hang1[N],hang2[N];
 7 bool vis[N],f,hang[N],lie[N];
 8 il int gi(){
 9     int a=0;char x=getchar();bool f=0;
10     while((x<‘0‘||x>‘9‘)&&x!=‘-‘)x=getchar();
11     if(x==‘-‘)x=getchar(),f=1;
12     while(x>=‘0‘&&x<=‘9‘)a=a*10+x-48,x=getchar();
13     return f?-a:a;
14 }
15 il void change1(int x[][N],int k){
16     for(int i=1;i<=m;i++)x[k][i]=1-x[k][i];
17 }
18 il void change2(int x[][N],int s,int t){
19     for(int i=1;i<=n;i++)swap(x[i][s],x[i][t]);
20 }
21 il bool check(int s[][N],int t[][N],int l1,int l2){
22     for(int i=1;i<=n;i++)
23         if(s[i][l1]!=t[i][l2])return 0;
24     return 1;
25 }
26 il void init(){
27     n=gi(),m=gi();f=0;
28     memset(hang1,0,sizeof(hang1));
29     memset(hang2,0,sizeof(hang2));
30     for(int i=1;i<=n;i++)
31         for(int j=1;j<=m;j++){
32         st[i][j]=gi();
33         if(st[i][j]==1)hang1[i]++;
34     }
35     for(int i=1;i<=n;i++){
36         for(int j=1;j<=m;j++){
37         ed[i][j]=gi();
38         if(ed[i][j]==1)hang2[i]++;
39         }
40         if(hang1[i]!=hang2[i]&&hang1[i]!=m-hang2[i])f=1;
41     }
42     if(f){puts("NO");return;}
43     for(int p=2;p<=m;p++){
44         memcpy(tmp,st,sizeof(st));
45         change2(tmp,1,p);
46         for(int i=1;i<=n;i++)
47             if(tmp[i][1]!=ed[i][1])change1(tmp,i);
48         for(int i=1;i<=m;i++){
49             f=0;
50             for(int j=i;j<=m;j++)
51             if(check(tmp,ed,j,i)){change2(tmp,i,j);f=1;break;}
52             if(!f)break;
53         }
54         if(f)break;
55     }
56     if(f){puts("YES");return;}
57     puts("NO");
58 }
59 int main(){
60     k=gi();
61     while(k--){
62         init();
63     }
64     return 0;
65 }

原文地址:https://www.cnblogs.com/five20/p/8909094.html

时间: 2024-10-28 01:50:21

P1275 魔板的相关文章

洛谷 P1275 魔板

P1275 魔板 题目描述 有这样一种魔板:它是一个长方形的面板,被划分成n行m列的n*m个方格.每个方格内有一个小灯泡,灯泡的状态有两种(亮或暗).我们可以通过若干操作使魔板从一个状态改变为另一个状态.操作的方式有两种: (1)任选一行,改变该行中所有灯泡的状态,即亮的变暗.暗的变亮: (2)任选两列,交换其位置. 当然并不是任意的两种状态都可以通过若干操作来实现互相转化的. 你的任务就是根据给定两个魔板状态,判断两个状态能否互相转化. 输入输出格式 输入格式: 文件中包含多组数据.第一行一个

hdu1430魔板(广搜+康托展开+string应用)

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2420    Accepted Submission(s): 511 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜色

hdu 魔板

#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <cmath> #include <string> #include <vector> #include <list> #include <map> #include <queue> #include <stack

ACM-康托展开+预处理BFS之魔板——hdu1430

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1679    Accepted Submission(s): 354 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版--魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜

Hdoj 1430 魔板 【BFS】+【康拓展开】+【预处理】

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2139    Accepted Submission(s): 452 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版--魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜

BFS [HDU 1430] 魔板

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1988    Accepted Submission(s): 407 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜色

【判重+广搜(bfs)】魔板

判重+广搜(bfs)]魔板 Time Limit: 1000MS Memory Limit: 32768KB Special Judge 有一个两行四列的魔板,每个格子里有一个1到8的数字(数字唯一),现在我们可以对魔板进行以下操作: 1.交换两行的数字. 2.将第一列移到第二列,第二列到第三列,第三列到第四列,第四列到第一列. 3.将中间四个数顺时针转一次. 现给你初始状态,我末状态请你用最小的步数将它从初始状态变到末状态. 输入: 前两行,每行4个数表示初状态. 后两行,每行4个数表示末状态

Sicily 1151 解题报告(魔板,广搜)

      I.     原题中文大意 魔板由2*4个方块组成,用1到8的数字表示不同的块. 其初始状态是 1 2 3 4 8 7 6 5 对魔板可进行三种基本操作,这三种基本操作,可将任一种状态装换成另一种状态. A (上下行互换) B (行循环右移一格) C (中间四块顺时针转90) 8 7 6 5 1 2 3 4 4 1 2 3 5 8 7 6 1 7 2 4 8 6 3 5 II.       算法思想及解题用到的主要数据结构 广度优先搜索,已搜索过的节点不再进行记录,保证第一个找到的解

ACM-双向BFS之魔板——求助ING!

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1675    Accepted Submission(s): 353 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版--魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜