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的更多相关文章

  1. 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 ...

  2. 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 ...

  3. 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 ...

  4. cf493D Vasya and Chess

    D. Vasya and Chess time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  5. 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 ...

  6. Gerald and Giant Chess

    Gerald and Giant Chess time limit per test 2 seconds memory limit per test 256 megabytes input stand ...

  7. CF559C Gerald and Giant Chess

    题意 C. Gerald and Giant Chess time limit per test 2 seconds memory limit per test 256 megabytes input ...

  8. E. Gerald and Giant Chess

    E. Gerald and Giant Chess time limit per test 2 seconds memory limit per test 256 megabytes2015-09-0 ...

  9. 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 ...

随机推荐

  1. Java 时间总结

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/80613024 本文出自[赵彦军的博客] 时区 整个地球分为二十四时区,每个时区都有 ...

  2. 【LeetCode】无重复字符串最长子串

    题目描述 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "a ...

  3. Spark数据倾斜及解决方案

    一.场景 1.绝大多数task执行得都非常快,但个别task执行极慢.比如,总共有100个task,97个task都在1s之内执行完了,但是剩余的task却要一两分钟.这种情况很常见. 2.原本能够正 ...

  4. OPPO A57 刷机(官方安装包)+完美Root+ 破解主题+屏蔽Root顶部红色框+NV修复

    朋友说她的手机被被人刷后,有许多预装的软件问我能不能处理下,让我装个纯净版. 开机可以看到预装了许多软件,通常想要删除预装软件就必须Root,于是下载刷机精灵,360刷机大师,线刷包之类的软件Root ...

  5. Multiple Server Query Execution报The result set could not be merged..

    在SQL Server中使用Multiple Server Query Execution这个功能做数据库维护或脚本发布时非常方便,昨天由于磁盘空间原因,删除清理了大量的软件和组件,结果导致SSMS客 ...

  6. ORACLE Index Lookup索引访问路径总结

    在ORACLE中,索引访问/查找(Index Lookup)路径有五种方式,分别为INDEX UNIQUE SCAN.INDEX RANGE SCAN.INDEX FULL SCAN.INDEX FA ...

  7. 【2018.08.13 C与C++基础】C++语言的设计与演化读书笔记

    先占坑 老实说看这本书的时候,有很多地方都很迷糊,但却说不清楚问题到底在哪里,只能和Effective C++联系起来,更深层次的东西就想不到了. 链接: https://blog.csdn.net/ ...

  8. 团队作业—预则立&&他山之石

    团队作业-预则立&&他山之石 Deadline: 2017.10.24 22:00pm 作业要求 一.确立团队选题,建立和初步熟悉团队git的协作方式.项目后续的代码.文档都要通过gi ...

  9. Teradata 批量查找PI字段

    select * from dbc.indicesv where indextype in ('P','Q');

  10. Mybatis之插件拦截

    参考:http://www.mybatis.org/mybatis-3/zh/configuration.html#plugins MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用.默 ...