POJ 3279 + UVA 11464 (二维翻转水题)
2015-12-04 21:49
399 查看
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代码:
UVA代码:
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 ; int ans ,n,m,now,res=INF; int cnt ; int pre ; int change ; 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 ; int num ,n; int tmp ,now,ans; bool change ; 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 [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; }
相关文章推荐
- shell编程高级之正则表达式
- Socket编程——第三方类库 AsyncSocket
- 【android_温故知新】第 3 组 UI 组件:ImageView 及其子类
- 一个简单的网页构造
- 7)查找[2]二叉排序树以及查找
- BZOJ1036 树的统计Count(同时求sum max)
- 从 xUtils 中发现的Android 6.0 版本更新问题
- 自增与自减运算
- theano学习——内置数据类型
- 初次拿到板子的兴奋
- leetcode Single Number III
- 树莓派(Raspberry pi)下安装七牛云c/c++ SDK时遇到的问题及解决方案
- poj1837Balance
- 查询json数据结构的8种方式
- crontab使用小结
- android119 侧滑菜单
- Qwt简介、下载、安装和使用
- nyoj 3 多边形重心问题 【几何】
- 《剑指offer》——数组中重复的数字
- 实验报告(实验五)