hdu 5113(2014北京—搜索+剪枝)
2015-10-06 17:27
323 查看
题意:有N*M的棋盘,用K种颜色去染,要求相邻块不能同色。已知每种颜色要染的块数,问能不能染,如果能,输出任一种染法。
最开始dfs失败了- -,优先搜索一行,搜完后进入下一列,超时。本来以为搜索不行,看别人给的思路就是搜索+剪枝。
但是一直不知道该怎么剪,看了解题报告才发现,剩下的格子的数量+1必需是剩余最多种类棋子的两倍,否则必定会有相邻存在。
例如 3*3的空格中,一类棋子最多只能占5个、
最开始dfs失败了- -,优先搜索一行,搜完后进入下一列,超时。本来以为搜索不行,看别人给的思路就是搜索+剪枝。
但是一直不知道该怎么剪,看了解题报告才发现,剩下的格子的数量+1必需是剩余最多种类棋子的两倍,否则必定会有相邻存在。
例如 3*3的空格中,一类棋子最多只能占5个、
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; int num[20]; int tmap[10][10]; int n,m,k; bool dfs(int x,int y) { for(int i = 1; i <= k; i++) if((n*m-(m*(x-1)+y-1)+1)/2<num[i]) return false; for(int i = 1; i <= k; i++) { bool flag = true; if(y - 1>= 1) { if(tmap[x][y-1] == i) flag = false; } if(x - 1>= 1) { if(tmap[x-1][y] == i) flag = false; } if(num[i] > 0 && flag) { tmap[x][y] = i; num[i]--; if(x == n && m == y) return true; if(y + 1 <= m) { if(dfs(x,y+1)) return true; } else { if(x + 1 <= n) if(dfs(x+1,1)) return true; } num[i]++; tmap[x][y] = -1; } } return false; } int main() { int T; scanf("%d",&T); int cas = 1; while(T--) { scanf("%d%d%d",&n,&m,&k); for(int i = 1; i <= k; i++) scanf("%d",&num[i]); memset(tmap,-1,sizeof(tmap)); printf("Case #%d:\n",cas++); if(dfs(1,1)) { printf("YES\n"); for(int i=1; i<=n; i++) { for(int j=1; j<m; j++) printf("%d ",tmap[i][j]); printf("%d\n",tmap[i][m]); } } else printf("NO\n"); } return 0; }
相关文章推荐
- 黑马程序员——OC语言基础---description方法介绍及重写
- 【整理】Android-Recovery Mode(recover模式详解)
- Oracle查询转换之视图合并
- ThreadPoolExecutor
- [译] --- GPUImage README.md
- 四校联训Round4心得体会
- Java面向对象(一)
- go语言 匿名变量
- 关于使用 Connect-Busboy 实现文件上传 优化说明
- ios图片压缩
- android studio 编译出错 非法字符 未结束的字符
- 离队后的杂念
- iOS之 LLDB调试常用命令
- Android系统在超级终端下必会的命令大全(adb shell命令大全)
- 交换两个数的值,不借助第三方变量.
- Android源码开发之获取当前时间的时分秒
- hdu 5112 (2014北京 水)
- 线程执行的主要流程
- 学习网站
- hdu 5112 (2014北京 水)