[HDU 5004 KAMI] dfs+bfs
来源:互联网 发布:广联达软件教学视频 编辑:程序博客网 时间:2024/05/15 07:03
题目
acm.hdu.edu.cn/showproblem.php?pid=5004
分析
此题给出了最小步数n<=8,显然是限制了dfs的深度,因此就是暴力搜索题。
注意到其实对于每次选择一个点变颜色等价于每次都对同一个点改变颜色。因此就可以枚举一个点,然后bfs做出与该点所在的联通块相邻的联通块都有哪些颜色,基于本体联通块的定义,这些颜色必定不同于该点的颜色,然后枚举要把该点变成哪些颜色(一定是bfs出的颜色中的一种),然后bfs染色,继续搜索就可以了。注意对于每个联通块,只需要处理其左上角的点就可以了。
经过kk303同学指出这种方法是错的。。。暂时还没有找到好方法。。。
代码
#include<cstring>#include<string>#include<cstdio>#include<cstdlib>#include<iostream>#include<vector>#include<cmath>#include<algorithm>#include<queue>#define ll long long#define pf printf#define sf scanf#define Fill(a,b) memset(a,b,sizeof(a))using namespace std;const int N = 16;const int M = 10;const int dx[] = {0,1,0,-1};const int dy[] = {1,0,-1,0};struct Point{ int x,y; Point(){} Point(int a,int b):x(a),y(b){};};char t[N][M],s[N][M];bool v[N][M];bool flag;int n,ans[10];queue<Point>q;inline bool judge(int x,int y){ if (x - 1 >= 0 && t[x - 1][y] == t[x][y]) return 0; if (y - 1 >= 0 && t[x][y - 1] == t[x][y]) return 0; return 1;}inline void init(){ for (int i = 0; i < N; i++) for (int j = 0; j < M; j++) s[i][j] = t[i][j];}inline bool check(){ char c = s[0][0]; for (int i = 0; i < N; i++) for (int j = 0; j < M; j++) if (s[i][j] != c) return 0; return 1;}inline void find_color(int x,int y,bool ok[]){ while (!q.empty()) q.pop(); q.push(Point(x,y)); char c = s[x][y]; Fill(v,0); while (!q.empty()) { Point p = q.front(); q.pop(); for (int i = 0; i < 4; i++) { x = p.x + dx[i]; y = p.y + dy[i]; if (x >= 0 && x < N && y >= 0 && y < M) { if (s[x][y] == c && !v[x][y]) { q.push(Point(x,y)); v[x][y] = 1; } else if (s[x][y] != c) ok[s[x][y] - '0'] = 1; } } }}inline void paint(int x,int y,char c){ while (!q.empty()) q.pop(); q.push(Point(x,y)); char tar = s[x][y]; s[x][y] = c; while (!q.empty()) { Point p = q.front(); q.pop(); for (int i = 0; i < 4; i++) { x = p.x + dx[i]; y = p.y + dy[i]; if (x >= 0 && x < N && y >= 0 && y < M && s[x][y] == tar) { q.push(Point(x,y)); s[x][y] = c; } } }}void dfs(int x,int y,int step){ if (step > n) return; if (flag) return; if (check()) { if (step == n) flag = 1; return; } if (step == n) return; bool ok[5] = {0,0,0,0,0}; char tmp[16][10]; for (int i = 0; i < N; i++) for (int j = 0; j < M; j++) tmp[i][j] = s[i][j]; find_color(x,y,ok); for (int i = 1; i <= 4; i++) if (ok[i]) { paint(x,y,i + '0'); ans[step + 1] = i; dfs(x,y,step + 1); if (flag) return; for (int j = 0; j < N; j++) for (int k = 0; k < M; k++) s[j][k] = tmp[j][k]; }}int main(){ //freopen("in.txt","r",stdin); int T; sf("%d",&T); for (int TT = 1; TT <= T; TT++) { sf("%d",&n); for (int i = 0; i < N; i++) sf("%s",s[i]); for (int i = 0; i < N; i++) for (int j = 0; j < M; j++) t[i][j] = s[i][j]; flag = 0; pf("Case #%d:\n",TT); for (int i = 0; i <= N; i++) { if (flag) break; for (int j = 0; j < M; j++) if (judge(i,j)) { init(); dfs(i,j,0); if (flag) { for (int k = 1; k <= n; k++) pf("%d %d %d\n",ans[k],i + 1,j + 1); break; } } } } return 0;}
0 0
- [HDU 5004 KAMI] dfs+bfs
- HDU - 5004 KAMI(回溯+dfs)
- kami
- HDU 1983 BFS + DFS
- HDU 1044 BFS + DFS
- hdu (4414)(BFS+DFS)
- hdu 1044 bfs dfs
- hdu 1044 DFS + BFS
- hdu 4101 DFS+BFS
- HDU 1983 DFS+BFS
- HDU 1044 BFS+DFS
- HDU 1044(bfs+dfs)
- hdu 1983(bfs+dfs)
- hdu 1044 (bfs+dfs)
- HDU 1983 BFS&&DFS
- HDU 1044 bfs+dfs
- hdu-2485-bfs+dfs
- hdu 1074 dfs or bfs
- 模板类与类模板、函数模板与模板函数等的区别
- 《Systems Performance: Enterprise and the Cloud》读书笔记系列(二) —— 第二章(一)
- 【HDU】5009 Paint Pearls DP
- Eclipse快捷键指南
- 编程之美:第一章 1.12拈石游戏分析
- [HDU 5004 KAMI] dfs+bfs
- 简单Linux C线程池
- 数据库设计三大范式
- 【刷题小记73】比较大小
- 程序员是不是应该加强运动?
- 编程之美:第一章 1.13 NIM两堆石头的游戏
- Roman to Integer
- 2013阿里巴巴软件测试笔试题
- 【Unity3D】Parallax Background循环背景(使用纹理)