CQOI2013 棋盘游戏
来源:互联网 发布:淘宝ipad横版 编辑:程序博客网 时间:2024/06/06 19:23
题目大意
在一个
两个棋子的初始位置会给出。询问你谁会胜利,并且需要多少回合。
解题思路
首先我们发现若一开始不是白棋就在黑子隔壁,它可以一步吃掉黑棋的话,黑棋绝对会获得胜利。
设最终的答案为
证明
设白棋坐标为
不妨假设
我们设白棋走一回合,黑棋走一回合总称为一次。
我们考虑一次总共可能出现的情况。
可以发现的是,每走一次,黑棋和白棋之间的曼哈顿距离都会减少1。
又因为两个点初始的曼哈顿距离最大为
得证。
知道我们的
我们设
设
若
若
那么
若
若
我们这里可以用记忆化搜索来做。
而且若当前
复杂度是
代码
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN = 25;const int xy[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};const int x2[4][2] = {{2,0},{0,2},{-2,0},{0,-2}};int F[105][MAXN][MAXN][MAXN][MAXN][2],N,step;int Dfs(int r1,int c1,int r2,int c2,int ctr,int dep){ if (r1 == r2 && c1 == c2) { if (ctr == 0) return F[dep][r1][c1][r2][c2][ctr] = 0; return F[dep][r1][c1][r2][c2][ctr] = -2; } if (dep > step) return -2; if (F[dep][r1][c1][r2][c2][ctr] != -1) return F[dep][r1][c1][r2][c2][ctr]; if (!ctr) { int pt = 0; for(int i = 0;i < 4;i ++) { int nx = r1 + xy[i][0],ny = c1 + xy[i][1]; if (nx && ny && nx <= N && ny <= N) { int tmp = Dfs(nx,ny,r2,c2,!ctr,dep + 1); if (tmp == -2) {pt = -2;break;} pt = max(pt,tmp + 1); } } return F[dep][r1][c1][r2][c2][ctr] = pt; } else { int pt = (1 << 30); for(int i = 0;i < 4;i ++) { int nx = r2 + xy[i][0],ny = c2 + xy[i][1]; if (nx && ny && nx <= N && ny <= N) { int tmp = Dfs(r1,c1,nx,ny,!ctr,dep + 1); if (tmp == -2) continue; pt = min(pt,tmp + 1); } } for(int i = 0;i < 4;i ++) { int nx = r2 + x2[i][0],ny = c2 + x2[i][1]; if (nx && ny && nx <= N && ny <= N) { int tmp = Dfs(r1,c1,nx,ny,!ctr,dep + 1); if (tmp == -2) continue; pt = min(pt,tmp + 1); } } if (pt == (1 << 30)) pt = -2; return F[dep][r1][c1][r2][c2][ctr] = pt; }}int main(){ int r1,c1,r2,c2; scanf("%d%d%d%d%d", &N, &r1, &c1, &r2, &c2); if (abs(r1 - r2) + abs(c1 - c2) <= 1) printf("WHITE 1\n"); else { step = 4 * N; { for(int j = 0;j <= step;j ++) memset(F[j],255,sizeof F[j]); Dfs(r1,c1,r2,c2,0,0); if (F[0][r1][c1][r2][c2][0] >= 0) {printf("BLACK %d\n", F[0][r1][c1][r2][c2][0]);return 0;} } printf("DRAW\n"); }}
- CQOI2013 棋盘游戏
- [CQOI2013]棋盘游戏
- bzoj3106: [cqoi2013]棋盘游戏 对抗搜索
- [CQOI2013]新Nim游戏
- cqoi2013 新Nim游戏
- bzoj3105: [cqoi2013]新Nim游戏
- bzoj3105【CQOI2013】新Nim游戏
- 3105: [cqoi2013]新Nim游戏
- BZOJ3105: [cqoi2013]新Nim游戏
- 【CQOI2013】bzoj3105 新Nim游戏
- bzoj3105 [cqoi2013]新Nim游戏
- 3105: [cqoi2013]新Nim游戏
- 棋盘游戏
- 棋盘游戏
- 棋盘游戏
- 棋盘游戏
- 棋盘游戏
- 棋盘游戏
- java命令模式
- 实现字典和对象转换的工具类
- js内置对象(概念)
- 当系统内存不足时如何优雅的关闭或退出应用。
- 你应该掌握的七种回归技术
- CQOI2013 棋盘游戏
- 重学Linux——笔记
- 为什么button在设置标题时要用一个方法,而不像lable一样直接用一个属性
- HDU 1249 三角形(平面分割 找规律)
- js内置对象(日期对象)
- linux下mysql常用
- Android UI设计:Button与RadoiButton
- 解决svn清理失败且路径显示乱码问题
- [C++11 并发编程] 08 - Mutex std::unique_lock