POJ3279-Fliptile

題目鏈接:POJ3279

思路很重要。

第一點,N最大隻有15 ,考慮到第一排的翻轉情況確定之後,整個棋盤的翻轉情況也就確定了。最多遍歷2^15種。

第二點,對於每一排的1,只有其下面的翻轉能將其變爲0,而不影響同行其他棋子的翻轉情況。

第三點,座標系的建立要統一,x,y,m,n,  x指的是row 那麼y指的是col ,都統一用一個座標系不容易錯。

這題目的思路值得借鑑,思考。不看他人的題解,我也想不到。

AC代碼;

#include<stdio.h>
#include<string.h>
const int maxn=20;
bool mp[maxn][maxn],ans[maxn][maxn],f[maxn][maxn],tmp[maxn][maxn];
int m,n,res=300;

void flip(int x,int y){
    tmp[x][y]=!tmp[x][y];
    if(x-1>=0) tmp[x-1][y]=!tmp[x-1][y];
    if(x+1<m) tmp[x+1][y]=!tmp[x+1][y];
    if(y-1>=0) tmp[x][y-1]=!tmp[x][y-1];
    if(y+1<n) tmp[x][y+1]=!tmp[x][y+1];
}

void print(bool t[maxn][maxn]){
  //  puts("");
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            printf("%d ",t[i][j]);
        }puts("");
    }
  //  puts("");
}

int main(){
    scanf("%d%d",&m,&n);
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++)
            scanf("%d",&mp[i][j]);
    }
    /*
   // check input
  // memcpy(f,mp,sizeof(mp));
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            printf("%d ",f[i][j]);
        }puts("");
    }
  //  */
    for(int i=0;i<(1<<n);i++){
     //   memcpy(f,mp,sizeof(mp));
     memset(f,false,sizeof(f));
     //printf("%d:",i);
        for(int j=0;j<n;j++){
            f[0][n-j-1]=(i>>j)&1;
           // printf("%d ",f[0][n-j-1]);
        }
      //  for(int j=0;j<n;j++) printf("%d ",f[0][j]);puts("");
        int fcnt=0;
        memcpy(tmp,mp,sizeof(mp));
        for(int j=0;j<n;j++){
            if(f[0][j]){
                flip(0,j);
                fcnt++;
            }
        }
        for(int j=0;j<m-1;j++){
            for(int k=0;k<n;k++){
                if(tmp[j][k]==1){
                    f[j+1][k]=1;
                    flip(j+1,k);
                    fcnt++;

                 //  if(i==0) printf("%d,%d\n",j+1,k);
                  // if(i==0) print(tmp);
                }
            }
        }
       // printf("fcnt=%d\n",fcnt);
        bool flag=true;
        for(int j=0;j<n;j++){
            if(tmp[m-1][j]) flag=false;
           // printf("%d ",tmp[m-1][j]);
        }
        //puts("");

        if(!flag) continue;
        else{
            if((fcnt<res)){
                memcpy(ans,f,sizeof(f));
                res=fcnt;
            }
        }
    }
   // printf("res:%d\n",res);

    memcpy(tmp,mp,sizeof(mp));
    if(res!=300) print(ans);
    else printf("IMPOSSIBLE\n");
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章