POJ 3279 Fliptile

来源:互联网 发布:服装设计要学什么软件 编辑:程序博客网 时间:2024/06/11 03:29

原题链结

恩...与白书上的思路一样 

枚举第0行翻转的所有情况 然后依次向下更新 

如果上一行为1,这一行肯定需要翻转,直到更新完(m-2)行

再检索一遍(m-1)行  如果(m-1)行都为0 这种情况符合题意 更新翻转的最少次数 记录下最优解

话不多说 上代码


#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<string>#include<stack>#include<queue>#include<cmath>#include<stack>#include<list>#include<map>typedef long long ll;using namespace std;int m,n;int tile[17][17],most[17][17],flip[17][17]; //tile是初始地图 most记录最优解 flip记录中间结果int nextx[5]={0,1,0,-1,0};int nexty[5]={1,0,-1,0,0};  //翻转一个格子,其实要翻转五个格子int get(int x,int y){    int c=tile[x][y];  // 初始时 坐标为(x,y)的格子的状态    for(int k=0;k<5;k++)    {        int tx=x+nextx[k],ty=y+nexty[k]; //更新到邻接格子        if(tx>=0&&tx<m&&ty>=0&&ty<n)        {            c+=flip[tx][ty];   //在初始状态的基础上加上翻转次数        }    }    return c%2;//如果为奇数 那么这个格子现在状态为1 也就是黑色}int cal(){    int i,k,j;    for(i=1;i<m;i++)    {        for(j=0;j<n;j++)        {            if(get(i-1,j)!=0) //上一行格子是1,说明这一行需要翻转            {                flip[i][j]=1;  //这个地方不要把邻接的格子都更新,在get函数里已经更新了!            }        }    }    for(j=0;j<n;j++)    {        if(get(m-1,j)!=0)return -1; //检索最后一行 是否全部为0    }    int res=0;    for(i=0;i<m;i++)    {        for(j=0;j<n;j++)        {            res+=flip[i][j];  //计算出总的翻转次数        }    }    return res;}int main(){    int i,j,k;    while(scanf("%d%d",&m,&n)==2)    {           int cnt=0;            for(i=0;i<m;i++)            for(j=0;j<n;j++)            {                scanf("%d",&tile[i][j]);                cnt+=tile[i][j];            }            if(cnt==0)            {                printf("0\n"); //全部为0 无需翻转                continue;            }        int ans=0xfffffff;        for(i=0;i< 1<<n;i++)        {            memset(flip,0,sizeof(flip));//不要忘记初始化,在这个地方WA了几次...开始时翻转次数都为0            for(j=0;j<n;j++)            {                flip[0][n-j-1]=i>>j&1;  //枚举第一行的翻转情况            }            int num=cal();            if(num>=0)            {                 if(ans>num)                 {                    ans=num;                    memcpy(most,flip,sizeof(flip));//更新res ,并保存最优解                 }            }        }        if(ans==0xfffffff)        {            printf("IMPOSSIBLE\n");        }        else{          for(i=0;i<m;i++)          {              for(j=0;j<n;j++)              {                 printf("%d%c",most[i][j],j+1==n?'\n':' ');              }          }        }    }    return 0;}


0 0
原创粉丝点击