-
Fliptile
- POJ - 3279
- 题意:
- 牛可以踩格子保证求一个最少踩的次数,最小状态下输出每个位置踩的次数
- 思路:
- 枚举第一层的状态依次就可以确定下面的状态。
- 注意递归回溯图修改恢复的处理。
-
#include <iostream> #include<cstring> #include<stdio.h> #include<algorithm> using namespace std; #define maxn 22 #define inf 0x3f3f3f3f #define ll long long ll t,n,m,ans,sum=inf; char gra[maxn][maxn],mmp[maxn][maxn],out[maxn][maxn],in[maxn][maxn],pr[maxn][maxn]; void check(int s) { memcpy(pr,out,sizeof(out)); for(int i=1; i<n; i++) for(int j=0; j<m; j++) { if(mmp[i-1][j]=='1') { out[i][j]='1'; mmp[i][j]=='1'?mmp[i][j]='0':mmp[i][j]='1'; mmp[i-1][j]='0'; if(j>0) mmp[i][j-1]=='1'?mmp[i][j-1]='0':mmp[i][j-1]='1'; if(j<m-1) mmp[i][j+1]=='1'?mmp[i][j+1]='0':mmp[i][j+1]='1'; if(i<n-1) mmp[i+1][j]=='1'?mmp[i+1][j]='0':mmp[i+1][j]='1'; s++; } } for(int i=0; i<m; i++) if(mmp[n-1][i]=='1') { memcpy(out,pr,sizeof(out)); return ; } if(s<sum) { sum=s; memcpy(in,out,sizeof(out)); } memcpy(out,pr,sizeof(out)); return ; } void dfs(int cnt,int s) { if(cnt>m) return; if(cnt==m) { memcpy(gra,mmp,sizeof(mmp)); check(s); memcpy(mmp,gra,sizeof(mmp)); return ; } out[0][cnt]='0'; dfs(cnt+1,s); out[0][cnt]='1'; if(mmp[0][cnt]=='1') { mmp[0][cnt]='0'; if(cnt>0) mmp[0][cnt-1]=='1'?mmp[0][cnt-1]='0':mmp[0][cnt-1]='1'; if(cnt<m-1) mmp[0][cnt+1]=='1'?mmp[0][cnt+1]='0':mmp[0][cnt+1]='1'; if(0<n-1) mmp[0+1][cnt]=='1'?mmp[0+1][cnt]='0':mmp[0+1][cnt]='1'; dfs(cnt+1,s+1); out[0][cnt]='0'; mmp[0][cnt]='1'; if(cnt>0) mmp[0][cnt-1]=='1'?mmp[0][cnt-1]='0':mmp[0][cnt-1]='1'; if(cnt<m-1) mmp[0][cnt+1]=='1'?mmp[0][cnt+1]='0':mmp[0][cnt+1]='1'; if(0<n-1) mmp[0+1][cnt]=='1'?mmp[0+1][cnt]='0':mmp[0+1][cnt]='1'; } else { if(cnt>0) mmp[0][cnt-1]=='1'?mmp[0][cnt-1]='0':mmp[0][cnt-1]='1'; if(cnt<m-1) mmp[0][cnt+1]=='1'?mmp[0][cnt+1]='0':mmp[0][cnt+1]='1'; if(0<n-1) mmp[0+1][cnt]=='1'?mmp[0+1][cnt]='0':mmp[0+1][cnt]='1'; mmp[0][cnt]='1'; dfs(cnt+1,s+1); out[0][cnt]='0'; mmp[0][cnt]='0'; if(cnt>0) mmp[0][cnt-1]=='1'?mmp[0][cnt-1]='0':mmp[0][cnt-1]='1'; if(cnt<m-1) mmp[0][cnt+1]=='1'?mmp[0][cnt+1]='0':mmp[0][cnt+1]='1'; if(0<n-1) mmp[0+1][cnt]=='1'?mmp[0+1][cnt]='0':mmp[0+1][cnt]='1'; } } int main() { memset(out,'0',sizeof(out)); scanf("%lld%lld",&n,&m); for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { getchar(); scanf("%c",&mmp[i][j]); } } dfs(0,0); if(sum==inf) { printf("IMPOSSIBLE\n"); return 0; } for(int i=0; i<n; i++) for(int j=0; j<m; j++) { if(j!=m-1) { printf("%c ",in[i][j]); } else { printf("%c\n",in[i][j]); } } return 0; }
Fliptile POJ -状压枚举第一层
最新推荐文章于 2019-11-27 20:59:22 发布