UVA10838 The Pawn Chess
UVA好题没人写系列,感觉可以稍稍练习一下面向对象编程的形式(大雾)
题意很简单,在国际象棋的棋盘中有一些兵,走到对方底线即为胜利,问最优决策下谁能获胜。并输出最小步数。
首先这里的棋盘都只有\(4\times 4\),意味这状态很小。
所以我们可以联想到用类似于Luogu P4576 [CQOI2013]棋盘游戏用对抗搜索的方式求解。
如果可以获胜就找最小步数,否则要失败的那一方应该找一个能苟活最久的状态走下去。
发现这个决策其实就是取\(\min,\max\),这里显然也可以记忆化,但状态数\(3^{16}\)加上多组数据实在带不动。
这个时候我们只能掏出对抗搜索的神奇剪枝了——\(alpha-beta\)剪枝。
原理和模板可以自行百度,其实就是一种最优性剪枝。
注意合理的实现方式,否则可能会让代码又臭又长。
CODE
#include<cstdio>
#include<vector>
#define RI register int
#define pb push_back
using namespace std;
const int N=4,INF=1e9;
struct status
{
char a[N+1][N+1]; //0 white turn,1 black turn
inline int isover(void)
{
for (RI i=0;i<N;++i)
{
if (a[0][i]=='P') return 0;
if (a[3][i]=='p') return 1;
} return -1;
}
inline void expand(int player,vector <status> &next)
{
if (!player)
{
for (RI i=1;i<4;++i) for (RI j=0;j<4;++j) if (a[i][j]=='P')
{
if (a[i-1][j]=='.') { status to=*this; to.a[i-1][j]='P'; to.a[i][j]='.'; next.pb(to); }
if (j&&a[i-1][j-1]=='p') { status to=*this; to.a[i-1][j-1]='P'; to.a[i][j]='.'; next.pb(to); }
if (j<3&&a[i-1][j+1]=='p') { status to=*this; to.a[i-1][j+1]='P'; to.a[i][j]='.'; next.pb(to); }
}
} else
{
for (RI i=0;i<3;++i) for (RI j=0;j<4;++j) if (a[i][j]=='p')
{
if (a[i+1][j]=='.') { status to=*this; to.a[i+1][j]='p'; to.a[i][j]='.'; next.pb(to); }
if (j&&a[i+1][j-1]=='P') { status to=*this; to.a[i+1][j-1]='p'; to.a[i][j]='.'; next.pb(to); }
if (j<3&&a[i+1][j+1]=='P') { status to=*this; to.a[i+1][j+1]='p'; to.a[i][j]='.'; next.pb(to); }
}
}
}
}st; int t;
inline int AlphaBeta_Search(status now,int step,int player,int alpha,int beta)
{
int res=now.isover(); if (!res) return INF-step; if (~res) return step-INF;
vector <status> next; next.clear(); now.expand(player,next);
int lim=next.size(); if (!lim) return player?INF-step:step-INF;
for (RI i=0;i<lim;++i)
{
res=AlphaBeta_Search(next[i],step+1,player^1,alpha,beta);
if (player) beta=res<beta?res:beta; else alpha=res>alpha?res:alpha;
if (beta<=alpha) break;
}
return player?beta:alpha;
}
int main()
{
for (scanf("%d",&t);t;--t)
{
for (RI i=0;i<4;++i) scanf("%s",st.a[i]);
int res=AlphaBeta_Search(st,0,0,-2*INF,2*INF); //res<0 means black will win
if (res<0) printf("black (%d)\n",res+INF); else printf("white (%d)\n",-res+INF);
}
return 0;
}
UVA10838 The Pawn Chess的更多相关文章
- CodeForces 559C Gerald and Giant Chess
C. Gerald and Giant Chess time limit per test 2 seconds memory limit per test 256 megabytes input st ...
- Codeforces Round #281 (Div. 2) D. Vasya and Chess 水
D. Vasya and Chess time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- CF A and B and Chess
A and B and Chess time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- cf493D Vasya and Chess
D. Vasya and Chess time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- codeforces 519A. A and B and Chess,
A. A and B and Chess time limit per test 1 second memory limit per test 256 megabytes input standard ...
- Gerald and Giant Chess
Gerald and Giant Chess time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- CF559C Gerald and Giant Chess
题意 C. Gerald and Giant Chess time limit per test 2 seconds memory limit per test 256 megabytes input ...
- E. Gerald and Giant Chess
E. Gerald and Giant Chess time limit per test 2 seconds memory limit per test 256 megabytes2015-09-0 ...
- Codeforces Round #313 (Div. 1) C. Gerald and Giant Chess DP
C. Gerald and Giant Chess Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest ...
随机推荐
- android常犯错误记录(一)
错误:Error:Error: Found item Attr/border_width more than one time 这个容易,属性相同了,按照提示查询一下找出来删了就行了,注意大小写很容易 ...
- pyinstaller打包错误 UnicodeDecodeError: 'gbk' codec can't decode byte 0xab in position 160:
注:我的博客原本在CSDN,现转到博客园,图片采用以前的图片,并没有盗图. 在将.py文件打包时,出现了下列错误 >>C:\Users\小呆\PycharmProjects\pycharm ...
- matlab练习程序(曲面拟合)
这里用到的还是最小二乘方法,和上一次这篇文章原理差不多. 就是首先构造最小二乘函数,然后对每一个系数计算偏导,构造矩阵乘法形式,最后解方程组. 比如有一个二次曲面:z=ax^2+by^2+cxy+dx ...
- MySQL5.7 搭建主从同步
性能更好的新服务器申请下来了,我们决定在2台新服务器上使用mysql5.7,并且使用主从同步.读写分离架构,很不幸这个任务落到了我的头上.读写分离是在业务代码中实现的,在此不做详述,介绍一下我搭建My ...
- python 冒泡、二分查找
冒泡: import random def _sort(_lst): count = 1 while count < len(_lst): for i in range(0, len(_lst) ...
- 翻译:MySQL "Got an Error Reading Communication Packet" Errors
前言: 本文是对Muhammad Irfan的这篇博客MySQL "Got an Error Reading Communication Packet" Errors的翻译,如有翻 ...
- css图片垂直水平居中及放大(实现水平垂直居中的效果有哪些方法?)
实现水平垂直居中方法有很多种: 一.万能法: 1.已知高度宽度元素的水平垂直居中,利用绝对定位和负边距实现. <style type="text/css"> .wrap ...
- 自动化测试基础篇--Selenium文件上传send_keys
摘自https://www.cnblogs.com/sanzangTst/p/8358165.html 文件上传是web页面上很常见的一个功能,自动化成功中操作起来却不是那么简单. 一般分两个场景:一 ...
- 解决PowerDesigner不同表输入相同字段名被禁止问题
选择"Tools -> Model Options"后,弹出如下图所示窗口: 这两个选项取消勾选
- 关于cisco日志的配置
实例: en conf t clock timezone GMT+8 #设置北京时间 exit clock set HH:MM:SS DAY MONTH YEAR #设置当前时间 service ...