魔板

魔板

【问题描述】

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

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

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

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

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

【输入】

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

  每组数据的第一行两个整数nm(0<nm100)

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

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

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

【输出】

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

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

【样例】

       panel.in                                      panel.out

       2                                               YES

       3 4                                             NO

       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

 

 

这题在《算法艺术与信息学竞赛》书中有提到,题目名称为“黑白按钮”,不再赘述。

 

在写程序的时候遇到一个低级错误:为了省事把 i,j 等用于循环的变量设为了全局变量,结果程序出错很长时间不知道因为什么。后来发现之后心想真是犯了一个不大不小的错误:在子函数中 i,j 改变了数值,回到main()之后导致循环提前结束!

这样的错误今后一定不能再犯。

 

以下是我的程序:

#include < stdio.h >
long  k,n,m;
long  b0[ 101 ][ 101 ],b1[ 101 ][ 101 ],tmp[ 101 ][ 101 ];
void  hang( long  xx[][ 101 ], long  x)
{
    
long i;
    
for(i=1;i<=m;i++)
      xx[x][i]
=1-xx[x][i];
}

void  lie( long  xx[][ 101 ], long  x, long  y)
{
    
long i,t;
    
for(i=1;i<=n;i++)
    
{
       t
=xx[i][x];
       xx[i][x]
=xx[i][y];
       xx[i][y]
=t;
    }

}

int  same( long  xx[][ 101 ], long  x, long  yy[][ 101 ], long  y)
{
    
long i;
    
for(i=1;i<=n;i++)
      
if(xx[i][x]!=yy[i][y])
        
return 0;
    
return 1;
}

int  main()
{
    
long i,j,p,l,flag;
    FILE 
*fin,*fout;
    fin
=fopen("panel.in","r");
    fout
=fopen("panel.out","w");
    fscanf(fin,
"%ld",&k);
    
for(l=1;l<=k;l++)
    
{
       fscanf(fin,
"%ld%ld",&n,&m);
       
for(i=1;i<=n;i++)
         
for(j=1;j<=m;j++)
           fscanf(fin,
"%ld",&b0[i][j]);
       
for(i=1;i<=n;i++)
         
for(j=1;j<=m;j++)
           fscanf(fin,
"%ld",&b1[i][j]);
       
//------Read In
       for(p=1;p<=m;p++)
       
{
          
for(i=1;i<=n;i++)
            
for(j=1;j<=m;j++)
              tmp[i][j]
=b0[i][j];
          
//------Copy
          lie(tmp,1,p);
          
for(i=1;i<=n;i++)
            
if(tmp[i][1]!=b1[i][1])
              hang(tmp,i);
          
for(i=1;i<=m;i++)
          
{
             flag
=0;
             
for(j=i;j<=m;j++)
              
if(same(tmp,j,b1,i))
               
{
                  lie(tmp,i,j);
                  flag
=1;
                  
break;
               }

             
if(!flag) break;
          }

          
if(flag) break;
       }

       
if(flag) fprintf(fout,"YES\n");
       
else fprintf(fout,"NO\n");
    }

    fclose(fin);
    fclose(fout);
return 0;
}

你可能感兴趣的:(魔板)