poj 3279 Filptile

来源:互联网 发布:java中无参构造方法 编辑:程序博客网 时间:2024/06/05 07:45

M代表横坐标,N代表纵坐标,res是最终的反转情况,tem是中间过程记录的某一种反转情况

init是初始输入的数据。

 

#include<stdio.h>
#define MAX_N 16
int init[MAX_N][MAX_N],res[MAX_N][MAX_N],tem[MAX_N][MAX_N];
int M,N;
int mov[][2]={0,0,0,1,0,-1,1,0,-1,0};
int color(int x,int y)//判断格子x,y现在的颜色,1代表黑色,代表白色
{
       int x1,y1,num,i;
       num=init[x][y];//首先是输入的颜色
       for(i=0;i<5;i++)
       {
            x1=x+mov[i][0];
            y1=y+mov[i][1];
            if(x1>=0&&x1<M&&y1>=0&&y1<N)
            num+=tem[x1][y1];//再加上  上下左右旁边格子是否翻动的情况
       }
      return num%2;//如果是偶数,则相当于格子是白色,否则就是黑色。
}
int calc(void)
{
       int i,j,sum;
       for(i=1;i<M;i++)
          for(j=0;j<N;j++)
          {
              if(color(i-1,j))//如果是黑色
              tem[i][j]=1;//那么就要反转这个黑色格子(i-1,j)下面的格子(i,j)
          }
      for(j=0;j<N;j++)//检查最后一行格子是否全是白色
          if(color(M-1,j))
                return -1;
       sum=0;
       for(i=0;i<M;i++)
          for(j=0;j<N;j++)
             sum+=tem[i][j];//计算反转的次数
       return sum;
}
int main(void)
{
       int i,j,sum,co;
       scanf("%d%d",&M,&N);
       for(i=0;i<M;i++)
           for(j=0;j<N;j++)
             scanf("%d",&init[i][j]);
       sum=-1;
       for(i=0;i<1<<N;i++)
       {
             memset(tem,0,sizeof(tem));
             for(j=0;j<N;j++)
                 tem[0][N-j-1]=i>>j&1;
             co=calc();
             if(co>0&&(sum<0||sum>co))
             {
                 sum=co;
                 memcpy(res,tem,sizeof(tem));
             }
       }
       if(sum<0)
              printf("IMPOSSIBLE\n");
       else
       {
              for(i=0;i<M;i++)
              {
                  for(j=0;j<N;j++)
                     printf("%d ",res[i][j]);
                  printf("\n");
              }
        }
}

0 0
原创粉丝点击