【P1738】NOIP2011Mayan游戏C++题解(搜索)
来源:互联网 发布:php培训后容易找工作吗 编辑:程序博客网 时间:2024/05/22 15:28
这搜索真的挺麻烦的
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxx = 5 + 5, maxy = 7 + 5, maxc = 10 + 5;int n, c;int a[maxx][maxy], cnt[maxc];bool f[maxx][maxy];int ans[maxx][3];void fall(int x){ for (int i = 0; i < 7; i++) { if (a[x][i] == 0) { int j = i + 1; while (j < 7 && a[x][j] == 0) j++; if ( j == 7) return; else swap(a[x][i], a[x][j]); } }}bool clear(){ bool flag = false; for (int i = 0; i < 5; i++) for (int j = 0; j < 7; j++) { if (!a[i][j]) continue; if ( i < 3 && a[i][j] == a[i+1][j] && a[i][j] == a[i+2][j]) { f[i][j] = true; f[i+1][j] = true; f[i+2][j] = true;} if ( j < 5 && a[i][j] == a[i][j+1] && a[i][j] == a[i][j+2]) { f[i][j] = true; f[i][j+1] = true; f[i][j+2] = true;} } for (int i = 0; i < 5; i++) for (int j = 0; a[i][j] && j < 7; j++) if (f[i][j]) { flag = true; cnt[a[i][j]]--; a[i][j] = 0; f[i][j] = 0; } for (int i = 0; i < 5; i++) fall(i); return flag;}int check(){ int minc = 0; for (int i = 1; i <= c; i++) if (cnt[i]) if (!minc || minc > cnt[i]) minc = cnt[i]; return minc;}void print(){ for (int i = 1; i <= n; i++) printf("%d %d %d\n", ans[i][0], ans[i][1], ans[i][2]); exit(0);}void dfs(int move){ int mem[maxx][maxy], memc[maxc]; for (int i = 0; i < 5; i++) for (int j = 0; j < 7; j++) mem[i][j] = a[i][j]; for (int i = 1; i <= c; i++) memc[i] = cnt[i];//数据复制 for (int i = 0; i < 5; i++) for (int j = 0; a[i][j] && j < 7; j++) for (int k = 1; k >= -1; k-=2) if (i+k >= 0 && i+k < 5) { if ((k == -1 && a[i-1][j]) || a[i][j] == a[i+k][j]) continue; ans[move][0] = i; ans[move][1] = j; ans[move][2] = k; swap(a[i][j], a[i+k][j]); fall(i); fall(i+k);//检测下落合法性 while (clear());//合并 int tmp = check();//返回的值为最少的颜色块数 if (move == n) { if (tmp == 0) print();//如果是已经完成 } else if (tmp > 2) dfs(move+1);//至少存在三个,继续合并 for (int i = 0; i < 5; i++)//后续处理,数据恢复 for (int j = 0; j < 7; j++) a[i][j] = mem[i][j]; for (int i = 1; i <= c; i++) cnt[i] = memc[i]; }}int main(){ scanf("%d", &n); memset(a, 0, sizeof(a)); memset(cnt, 0, sizeof(cnt)); memset(ans, 0, sizeof(ans)); memset(f, 0, sizeof(f)); c = 0; int tmp; for (int i = 0; i < 5; i++) for (int j = 0; j <= 7; j++) { scanf("%d", &tmp); if (tmp == 0) break; a[i][j] = tmp; c = max(c, tmp); cnt[tmp]++; } dfs(1); printf("-1\n"); return 0;}
0 0
- 【P1738】NOIP2011Mayan游戏C++题解(搜索)
- NOIP2011Mayan 游戏
- 基础搜索算法题解(A-C)
- (题解)搜索的目录
- 搜索题解
- 搜索题解
- (题解)(搜索)POJ2069 Super Star
- HDU 3810 Magina 题解(搜索)
- Uva11988 Broken Keyboard 题解(搜索算法)
- 细胞个数题解(广度优先搜索)
- [题解] 八数码问题 (哈希表+搜索)
- 黑白棋游戏 (codevs 2743)题解
- Mayan游戏 (codevs 1136)题解
- 51Nod1381 硬币游戏(概率+题解)
- 1831 小C的游戏 (规律or记忆化搜索)
- 有道搜索框题解
- Frenemies题解搜索DFS
- 搜索练习题【题解】
- 郝斌老师C语言零基础自学专讲180集完整版
- 完成端口服务
- [Leetcode]Palindrome Partitioning
- HIVE优化总结
- FNDLOAD 笔记
- 【P1738】NOIP2011Mayan游戏C++题解(搜索)
- JavaScript回顾(7)
- HDU 2159 FATE(二维dp背包)
- Android权限之二packages.xml解析
- 有关js的history,无刷新跳到页面顶部
- unity3d模型制作规范
- 自适应网页设计(Responsive Web Design)--转载自http://www.ruanyifeng.com/blog/2012/05/responsive_web_design.html
- Android横竖屏切换总结
- 如何保证某个函数只被调用一次