2011 ACM/ICPC 北京赛区现场赛解题:GemAnd Prince
来源:互联网 发布:最强nba主网络断开 编辑:程序博客网 时间:2024/05/16 17:34
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4090
模拟+搜索:对于每一个局面,用bfs穷举出下一步所有可能存在的消除宝石的方法,每发现这样的一个方法就dfs进入下一层。
(即通过floodfill的方法进行bfs,每得到一个大小大于2的连通块的时候就dfs递归深入下去。这样可以让下面的剪枝得到很好的效果,可以将搜索树的size大大减小。)
剪枝:对于每一个局面,记录它通过之前的步骤已经得到的分数,然后维护它还可能得到的最大的分数(比如已经得到了120分,还有5个红色宝石,4个蓝色宝石,2个黑色宝石,那此局面可能得到的分数一定不超过120+5*5+4*4),通过用这个分数与当前已经得到的最大分数进行比较来进行剪枝。对于大多数数据这个剪枝能剪掉99.9%的节点,所以有时可以跑过10*9的数据,但是这个剪枝也是不稳定的,存在不少数据能把它卡掉。不过对于题目的最大上限8*8,这个剪枝已经足够了。
代码:
#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>using namespace std;int n, m, k;int mp[10][10];bool v2[10][10];int xx[8] = {0, 0, 1, -1, 1, -1, 1, -1};int yy[8] = {1, -1, 0, 0, 1, -1, -1, 1};int cnt, ans, sum;bool in(int x, int y){if (x <= n && x >= 1 && y <= m && y >= 1) return true;return false;}void dfs(int x, int y, int tt[10][10], int p, bool vv[10][10]){vv[x][y] = 1;cnt++;for (int i = 0; i < 8; ++i){if (in(x + xx[i], y + yy[i]) && !vv[x + xx[i]][y + yy[i]] && tt[x + xx[i]][y + yy[i]] == p){dfs(x + xx[i], y + yy[i], tt, p, vv);}}}void dfs2(int x, int y, int tt[10][10], int p){v2[x][y] = 1;tt[x][y] = 0;for (int i = 0; i < 8; ++i){if (in(x + xx[i], y + yy[i]) && !v2[x + xx[i]][y + yy[i]] && tt[x + xx[i]][y + yy[i]] == p){dfs2(x + xx[i], y + yy[i], tt, p);}}}void move(int tt[10][10]){int i, j, a[10], cc;for (i = 1; i <= 8; ++i) a[i] = 0;for (i = 1; i <= m; ++i){cc = 0;for (j = 1; j <= n; ++j) if (tt[j][i] > 0) { a[++cc] = tt[j][i]; }for (j = 1; j <= n - cc; ++j) tt[j][i] = 0;for (j = 1; j <= cc; ++j){tt[j + n - cc][i] = a[j];}}for (j = 1; j <= m; ++j){cc = 0;for (i = 1; i <= n; ++i) if (tt[i][j] > 0) cc++;a[j] = cc;}int tp[10];for (i = 1; i <= n; ++i){int tc = 0;for (j = 1; j <= m; ++j) if (a[j] == 0) { continue; } else { tp[++tc] = tt[i][j]; }for (j = 1; j <= tc; ++j) tt[i][j] = tp[j];for (j = tc + 1; j <= m; ++j) tt[i][j] = 0;}}void click(int tt[10][10], int s, int *a, int x, int y){int i, j;int ta[7], tmp[10][10];bool vv[10][10];int ts = s;for (i = 1; i <= k; ++i){if (a[i] >= 3) ts += a[i] * a[i];}if (ts < ans) return;for (int ii = 1; ii <= n; ++ii){for (int jj = 1; jj <= m; ++jj){vv[ii][jj] = 0;v2[ii][jj] = 0;tmp[ii][jj] = tt[ii][jj];}}if (x != 0 && y != 0) dfs2(x, y, tmp, tmp[x][y]);move(tmp);for (i = 1; i <= n; ++i){for (j = 1; j <= m; ++j){if (!vv[i][j] && tmp[i][j] > 0){for (int ii = 1; ii <= k; ++ii) ta[ii] = a[ii];cnt = 0;dfs(i, j, tmp, tmp[i][j], vv);if (cnt >= 3){ta[tmp[i][j]] -= cnt;click(tmp, s + cnt * cnt, ta, i, j);}}}}ans = max(ans, s);}int main(){int i, j, a[7];while (scanf("%d%d%d", &n, &m, &k) != EOF){memset(a, 0, sizeof(a));memset(v2, 0, sizeof(v2));for (i = 1; i <= n; ++i){for (j = 1; j <= m; ++j){scanf("%d", &mp[i][j]);if (mp[i][j] > 0) a[mp[i][j]]++;}}ans = 0;click(mp, 0, a, 0, 0);printf("%d\n", ans);}}
- 2011 ACM/ICPC 北京赛区现场赛解题:GemAnd Prince
- 2011 ACM/ICPC 北京赛区现场赛解题:Activation
- 2011 ACM/ICPC 北京赛区现场赛解题:Qin Shi Huang's National Road System
- 2011 ACM/ICPC 北京赛区现场赛解题:Peach Blossom Spring
- 2011 ACM/ICPC 北京赛区现场赛解题:ALetter to Programmers
- 2011 ACM/ICPC 北京赛区 J题 Gem and prince
- 2014 ACM/ICPC 北京赛区现场赛总结!!
- HDU 5117 Fluorescent(2014 ACM/ICPC 北京赛区现场赛)
- 2014 ACM/ICPC 北京赛区网络赛解题报告汇总
- 2011 ACM/ICPC 福州赛区现场赛8.7
- 2014北京赛区现场赛解题报告
- BUPT 238 2011ACM北京赛区现场赛A题
- HDU-5112-A Curious Matt (2014ACM/ICPC北京赛区现场赛A题!)
- HDU-5122-K.Bro Sorting (2014ACM/ICPC北京赛区现场赛K题!)
- HDU-5112-A Curious Matt (2014ACM/ICPC北京赛区现场赛A题!)
- HDU 5115 Dire Wolf(2014ACM/ICPC北京赛区现场赛D)
- 2013 ACM/ICPC 长沙赛区现场赛A题 解题报告
- 2014 ACM/ICPC 鞍山赛区现场赛 D&I 解题报告
- Linux内核制作与嵌入式根文件系统的构建
- 2011 ACM/ICPC 北京赛区现场赛解题:Activation
- Windows下mysql自动备份的几种方法
- Shell读取文件时变量作用域
- android:一个容易被遗忘的强大工具
- 2011 ACM/ICPC 北京赛区现场赛解题:GemAnd Prince
- 判断垂直滚动条的出现
- Confidence
- activity的launchMethod
- 2011 移动开发者大会 记忆中的第一天
- pyExcelerator django 创建可供下载的 excel
- DM8168的HDVPSS及评估板上的视频输入输出
- openlayers 配置 proxy
- DM8168 HDVPSS特点