HDU 5163 状压DP
2016-01-24 10:21
351 查看
HDU 5163
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5613
题意:
给一个矩阵,矩阵的值为原来矩阵此位置所在的九宫格里所有数字和(均为01)
还原出原来的矩阵。
思路:
状压枚举第一列的状态,然后递推后面状态就可以,很简单的模型题。
然而并不知道怎么合法,看到别人有用左上角的g值来推右下角,瞬间感觉智商再一次被碾压……详见代码
原来想合着一起发的,突然发现这题还没人发代码赶紧来一发赚一赚访问量[京都脸]
源码:
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5613
题意:
给一个矩阵,矩阵的值为原来矩阵此位置所在的九宫格里所有数字和(均为01)
还原出原来的矩阵。
思路:
状压枚举第一列的状态,然后递推后面状态就可以,很简单的模型题。
然而并不知道怎么合法,看到别人有用左上角的g值来推右下角,瞬间感觉智商再一次被碾压……详见代码
原来想合着一起发的,突然发现这题还没人发代码赶紧来一发赚一赚访问量[京都脸]
源码:
[code]#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <string> #include <algorithm> #include <iostream> using namespace std; int g[105][105]; int out[105][105]; int output[105][105]; int n, m; int cal(int i, int j) { int ans = g[i][j]; for(int t1 = -1 ; t1 <= 1 ; t1++){ for(int t2 = -1 ; t2 <= 1 ; t2++){ if(t1 == 1 && t2 == 1) continue; ans -= out[i + t1][j + t2]; } } return ans; } bool check(int i, int j) { int temp = 0; for(int t1 = -1 ; t1 <= 1 ; t1++){ for(int t2 = -1 ; t2 <= 1 ; t2++){ temp += out[i + t1][j + t2]; } } if(temp == g[i][j]) return true; return false; } bool valid(int s) { if((1 << n) & s) return false; for(int i = 1 ; i <= m ; i++) out[1][i] = out [i] = 0; for(int i = 2 ; i <= n - 1 ; i++){ if((1 << i) & s) out[i][1] = 1; else out[i][1] = 0; } // printf("s = %d\n"); // for(int i = 0 ; i < n ; i++) printf("%d ", out[i][0]); // printf("\n"); for(int j = 2 ; j <= m ; j++){ for(int i = 2 ; i <= n - 1 ; i++){ out[i][j] = cal(i - 1, j - 1); if(out[i][j] > 1 || out[i][j] < 0) return false; } for(int i = 1 ; i <= n ; i++){ if(!check(i, j - 1)) return false; } } for(int i = 1 ; i <= n ; i++) if(!check(i, m)) return false; for(int i = 1 ; i <= n ; i++) for(int j = 1 ; j <= m ; j++) output[i][j] = out[i][j]; // for(int i) return true; } int main() { // freopen("HDU 5163.in", "r", stdin); int T; scanf("%d", &T); while(T--){ scanf("%d%d", &n, &m); memset(g, 0, sizeof(g)); memset(out, 0, sizeof(out)); for(int i = 1 ; i <= n ; i++) for(int j = 1 ; j <= m ; j++) scanf("%d", &g[i][j]); int ok = 0; for(int s = 0 ; s < (1 << (n + 1)); s += 4){ if(valid(s)){ // printf("s = %d\n", s); ok++; } } if(ok == 0) printf("Impossible\n"); else if(ok >= 2) printf("Multiple\n"); else{ for(int i = 1 ; i <= n ; i++){ for(int j = 1 ; j <= m ; j++){ printf("%d", output[i][j]); if(j == m) printf("\n"); else printf(" "); } } } } return 0; }
相关文章推荐
- js放到哪记录
- 程序员的爱情
- 最大子列和
- 快速排序笔记
- MAC COCOA call command 调用终端控制台程序
- 在JDK源码中搜索设计模式的例子
- android之本地文件读取
- 手动备份升级WordPress
- 判断任意两台计算机的IP地址是否属于同一子网络的两种地址转换方法
- 【Groovy手札】Groovy的List
- POJ 2485(最小生成树)
- python ftplib模块编写简单的ftp服务
- 无偏估计与自由度
- java基础学习笔记
- Springmvc(5)之多部件表单、json交互和拦截器
- 分享js document.all的用法
- Java SimpleDateFormat parse 遭遇unparsable date异常
- 求方差时为什么要除以N—1,而不是除以N!【通俗理解-非数学专业】
- APUE_内存管理
- rspec 单元测试问题