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;
}

最新文章

  1. 怎么在MindManager中查看打印预览
  2. 处理Assetbundle依赖关系时想到的一道题
  3. sql 查询执行的详细时间profile
  4. 关于block使用的5点注意事项
  5. PHP基础示例:用PHP+Mysql编写简易新闻管理系统[转]
  6. HTML5 webapp框架
  7. (转)Android SlidingTabLayout定制分割线和指示条颜色
  8. Linux中的.emacs文件
  9. 获取iOS设备属性
  10. cocos2dX 之CCParticle
  11. Hibernate框架注解
  12. mysql5.6源码自动安装脚本
  13. 浅谈WPF中的PreviewTextInput
  14. Mysqli扩展类
  15. C#-MVC开发微信应用(3)--文本消息和图文消息的应答
  16. NOIP模拟测试1(2017081501)
  17. 微软BI 之SSAS 系列 - 在 SQL Server 2012 下查看 SSAS 分析服务的模型以及几个模型的简单介绍
  18. 我所理解的event loop
  19. Redis 在 LINUX 系统下 安装, 启动
  20. Unity3d ugui 实现image代码换图

热门文章

  1. react 会员登录
  2. 你不可不知的Java引用类型【总结篇】
  3. struts2从认识到细化了解
  4. (转载)彻底的理解:WebService到底是什么?
  5. C#-简介(一)
  6. Apache kylin 入门
  7. 虚拟机备份,部署VDP
  8. UUID生成随机字符串
  9. Java断言(Assertion)
  10. 网络协议与OSI体系结构