POJ 3279 + UVA 11464 (二维翻转水题)
来源:互联网 发布:sql 注入漏洞 关键字 编辑:程序博客网 时间:2024/06/02 07:17
http://poj.org/problem?id=3279
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2459
两题都是翻转一个数,然后它的上下左右都跟着变化。
这种题目的做法是用DFS枚举出第一行的所有状态,当第一行的状态确定之后,那么下面的状态也唯一了。因为下一行总是依赖上一行。然后对于每种状态check后求值就可了。
POJ代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 20;const int INF = 0x3f3f3f3f;int ismap[N][N];int ans[N][N],n,m,now,res=INF;int cnt[N][N];int pre[N][N];int change[N];bool check(int k){ if(k==n+1) { for(int i=1;i<=m;i++) { if(pre[k-1][i]) return false; } return true; } for(int i=1;i<=m;i++) { if(pre[k-1][i]) { cnt[k][i]++; now++; pre[k-1][i] = 0; pre[k][i] = pre[k][i] ? 0 : 1 ; if(i>1) pre[k][i-1] = pre[k][i-1] ? 0: 1; if(i<m) pre[k][i+1] = pre[k][i+1] ? 0 : 1; if(k+1<=n) pre[k+1][i] = pre[k+1][i] ? 0 : 1; } } check(k+1);}void dfs(int num){ if(num==m+1) { for(int i=1;i<=m;i++) { if(!change[i]) continue; now ++; cnt[1][i] ++; pre[1][i] = pre[1][i] ? 0 : 1; if(n>=2) pre[2][i] = pre[2][i] ? 0: 1; if(i>1) pre[1][i-1] = pre[1][i-1] ? 0 : 1; if(i<m) pre[1][i+1] = pre[1][i+1] ? 0: 1; } if(check(2) && now < res) { memcpy(ans,cnt,sizeof(ans)); res = now; } now = 0; memset(cnt,0,sizeof(cnt)); memcpy(pre,ismap,sizeof(pre)); return; } for(int ch = 0; ch<2 ; ch++) { if(!ch) dfs(num+1); else { change[num] = 1; dfs(num+1); change[num] = 0; } } return;}int main(){ while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&ismap[i][j]),pre[i][j] = ismap[i][j]; now = 0; res = INF; memset(cnt,0,sizeof(cnt)); memset(change,false,sizeof(change)); dfs(1); if(res==INF) printf("IMPOSSIBLE\n"); else for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) printf("%d%c",ans[i][j],j==m?'\n':' '); } return 0;}
UVA代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 20;const int INF = 0x3f3f3f3f;int party[N][N];int num[N][N],n;int tmp[N][N],now,ans;bool change[N];int sum(int i,int j){ int sum = 0; if(i-1>=1) sum+=num[i-1][j]; if(i+1<=n) sum+=num[i+1][j]; if(j-1>=1) sum+=num[i][j-1]; if(j+1<=n) sum+=num[i][j+1]; return sum;}void update(int i,int j){ if(i-1>=1) tmp[i-1][j]++; if(i+1<=n) tmp[i+1][j]++; if(j-1>=1) tmp[i][j-1]++; if(j+1<=n) tmp[i][j+1]++; return;}bool check(int k){ if(k==n+1) { for(int i=1;i<=n;i++) if(tmp[n][i]%2) return false; return true; } for(int i=1;i<=n;i++) { if(tmp[k-1][i]%2) { if(num[k][i]) return false; now ++; update(k,i); } } check(k+1);}void dfs(int x){ if(x==n+1) { for(int i=1;i<=n;i++) { if(!change[i]) continue; now++; update(1,i); } if(check(2)) ans = min(ans,now); memcpy(tmp,party,sizeof(tmp)); now = 0; return; } if(num[1][x]) dfs(x+1); else { for(int ch = 0; ch<2; ch++) { if(!ch) dfs(x+1); else{ change[x] = true; dfs(x+1); change[x] = false; } } } return;}int main(){ int T; scanf("%d",&T); for(int cas = 1;cas<=T;cas++) { scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&num[i][j]); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) party[i][j] = sum(i,j); memset(change,false,sizeof(change)); memcpy(tmp,party,sizeof(tmp)); now = 0; ans = INF; dfs(1); if(ans ==INF) ans = -1; printf("Case %d: %d\n",cas,ans); } return 0;}
0 0
- POJ 3279 + UVA 11464 (二维翻转水题)
- POJ 3279 Fliptile (翻转问题)
- POJ-3279 经典翻转问题
- ***POJ 3279 Fliptile【格子翻转】
- poj 3279(翻转问题贪心)
- POJ 3274 (翻转||关灯)
- 二维数组翻转
- UVA 11437 Triangle Fun 三角形趣题 (二维几何)
- poj 2275 模拟(翻转汉诺塔)
- poj 3279--Fliptile(二维反转)
- POJ 2019(二维RMQ)
- android二维图形翻转效果
- POJ 2029 二维树状数组(400题纪念)
- POJ 2155 Matrix (二维树状数组+经典题)
- POJ-1195 Mobile phones(二维树状数组裸题)
- poj 1195 (二维树状数组入门,模板题)
- poj 1195 二维线段树(模板题)
- [Uva 11990] "Dynamic" Inversion (二维分块)
- 8086汇编语言(灵活定位内存)
- python基础教程共60课-第2课print
- OpenJudge_P1788 Pell数列(递推)
- VC编程中经常能遇到LNK2005错误
- tomcat7部署war包出错
- POJ 3279 + UVA 11464 (二维翻转水题)
- project euler 14
- pat 1068 Find More Coins (30)
- 【以太网数据包】DNS数据包
- project euler 15
- 在Spring3+Hibernate4环境中配置Quartz定时器,注入sessionFactory
- PAT甲级-1004
- OpenJudge_P1760 菲波那契数列(2)(递推)
- project euler 16