心如止水
Je n'ai pas le temps
posts - 400,comments - 130,trackbacks - 0

【问题描述】

       有这样一种魔板:它是一个长方形的面板,被划分成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;
}

posted on 2010-01-06 18:43 lee1r 阅读(447) 评论(0)  编辑 收藏 引用 所属分类: 题目分类:搜索

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理