Description

 

Axel and Birgit like to play a card game in which they build a house of cards, gaining (or losing) credits as they add cards to the house. Since they both have very steady hands, the house of cards never collapses. They use half a deck of standard playing cards. A standard deck has four suits, two are red and two are black. Axel and Birgit use only two suits, one red, one black. Each suit has 13 ranks. We use the notation 1R2R, ..., 13R1B2B, ..., 13B to denote ranks and colors.

The players begin by selecting a subset of the cards, usually all cards of rank up to some maximum value M. After shuffling the modified deck, they take eight cards from the top of the deck and place them consecutively from left to right to form four ``peaks." For instance, if M = 13 and if the first ten cards (from 26) are:

6B 3R 5B 2B 1B 5R 13R 7B 11R 1R ...

then the game starts off with four peaks and three valleys as shown in Figure 7.

Figure 7: Peaks and valleys formed by the top 8 cards in the deck.

The remaining cards are placed face up, in a single row.

Each player is identified with a color, red or black. Birgit is always black and Axel is always red. The color of the first card used for the peaks and valleys determines which player has the first turn. For the example in Figure 7, Birgit has the first turn since the first card is 6B.

Players alternate taking turns. A turn consists of removing the card from the front of the row of cards and then doing one of the following:

  1. Holding the card until the next turn (this is a ``held card").
  2. Covering the valley between two peaks with the drawn card or the held card, forming a ``floor". The remaining card, if any, is held.
  3. Placing two cards over a floor, forming a peak (one of the cards must be a ``held'' card).

Not all options are always available. At most one card may be held at any time, so the first option is possible only if the player is not already holding a card.

Since the cards in the row are face up, both players know beforehand the order in which the cards are drawn.

If the player forms a downward-pointing triangle by adding a floor, or an upward-pointing triangle by adding a peak, then the scores are updated as follows. The sum of the ranks of the three cards in the triangle is added to the score of the player whose color is the same as the majority of cards in the triangle. If no triangle is formed during a play, both scores remain unchanged.

In the example from Figure 7, if Birgit places her card (11R) on the middle valley, she gains 14 points. If she places her card on the left valley, Axel gains 19 points. If she places her card on the right valley, Axel gains 29 points.

If no more cards remain to be drawn at the end of a turn, the game is over. If either player holds a card at this time, the rank of that card is added to (subtracted from) that player's score if the color of the card is the same as (different from) that player's color.

When the game is over, the player with the lower score pays a number of Swedish Kronor (Kronor is the plural of Krona) equal to the difference between the two scores to the other player. In case of a tie there is no pay out.

You must write a program that takes a description of a shuffled deck and one of the players' names and find the highest amount that player can win (or the player's minimum loss), assuming that the other player always makes the best possible moves.

Input

The input file contains multiple test cases representing different games. Each test case consists of a name (either `Axel' or `Birgit'), followed by a maximum rank M ( 5M13), followed by the rank and color of the 2M cards in the deck in their shuffled order. Every combination of rank (from 1 through M) and color will appear once in this list. The first eight cards form the initial row of peaks from left to right in the order drawn, and the remaining items show the order of the rest of the cards.

The final test case is followed by a line containing the word `End'.

Output

For each test case, print the test case number (starting with 1), the name of the player for the test case, and the amount that the player wins or loses. If there is a tie, indicate this instead of giving an amount. Follow the sample output format.

题目大意:略。

思路:剪枝搜索。

代码(1895MS):

 #include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std; const int UP = ;
const int FLOOR = ;
const int DOWN = ;
const int INF = 0x7fffffff; int deck[];
char s[], c;
int n; inline int abs(int x) {int y = x >> ; return (x + y) ^ y;} inline int getScore(int a, int b, int c) {
int ret = abs(a) + abs(b) + abs(c);
int sgn = (a > ) + (b > ) + (c > );
if(sgn > ) return ret;
else return -ret;
} struct State {
int card[], type[];
int hold[];
int pos, score; State() {
for(int i = ; i < ; ++i) {
card[i] = deck[i];
type[i] = (i % == ) ? UP : DOWN;
}
hold[] = hold[] = score = ;
pos = ;
} bool isFinal() {
if(pos == * n) {
score += hold[] + hold[];
hold[] = hold[] = ;
return true;
}
return false;
} State child() const {
State s;
memcpy(&s, this, sizeof(s));
s.pos = pos + ;
return s;
} void expand(int player, vector<State> &ret) const {
int &cur = deck[pos];
if(hold[player] == ) {
State s = child();
s.hold[player] = cur;
ret.push_back(s);
}
for(int i = ; i < ; ++i) if(type[i] == DOWN && type[i + ] == UP) {
State s = child();
s.score += getScore(card[i], card[i + ], cur);
s.type[i] = s.type[i + ] = FLOOR;
s.card[i] = s.card[i + ] = cur;
ret.push_back(s);
if(hold[player] != ) {
State s = child();
s.score += getScore(card[i], card[i + ], hold[player]);
s.type[i] = s.type[i + ] = FLOOR;
s.card[i] = s.card[i + ] = hold[player];
s.hold[player] = cur;
ret.push_back(s);
}
}
if(hold[player] != ) {
for(int i = ; i < ; ++i) if(type[i] == FLOOR && type[i + ] == FLOOR && card[i] == card[i + ]) {
State s = child();
s.score += getScore(card[i], hold[player], cur);
s.type[i] = UP; s.type[i + ] = DOWN;
s.card[i] = cur; s.card[i + ] = hold[player]; s.hold[player] = ;
ret.push_back(s);
swap(s.card[i], s.card[i + ]);
ret.push_back(s);
}
}
}
}; int alphabeta(State &s, int player, int alpha, int beta) {
if(s.isFinal()) return s.score;
vector<State> children;
s.expand(player, children);
int n = children.size();
for(int i = ; i < n; ++i) {
int v = alphabeta(children[i], player ^ , alpha, beta);
if(!player) alpha = max(alpha, v);
else beta = min(beta, v);
if(beta <= alpha) break;
}
return !player ? alpha : beta;
} int main() {
int t = ;
while(scanf("%s", s) != EOF && *s != 'E') {
scanf("%d", &n);
for(int i = ; i < * n; ++i) {
scanf("%d%c", &deck[i], &c);
if(c == 'B') deck[i] = -deck[i];
}
int start = !(deck[] > );
State beg;
int ans = alphabeta(beg, start, -INF, INF);
printf("Case %d: ", ++t);
if(s[] == 'B') ans = -ans;
if(ans == ) puts("Axel and Birgit tie");
else if(ans > ) printf("%s wins %d\n", s, ans);
else printf("%s loses %d\n", s, -ans);
}
}

UVA 1085 House of Cards(对抗搜索)的更多相关文章

  1. UVA - 10118Free Candies(记忆化搜索)

    题目:UVA - 10118Free Candies(记忆化搜索) 题目大意:给你四堆糖果,每一个糖果都有颜色.每次你都仅仅能拿随意一堆最上面的糖果,放到自己的篮子里.假设有两个糖果颜色同样的话,就行 ...

  2. BZOJ 3106: [cqoi2013]棋盘游戏(对抗搜索)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3106 对抗搜索,f[x][y][a][b][c][d]表示当前谁走,走了几步,及位置. (因为 ...

  3. BZOJ.5248.[九省联考2018]一双木棋chess(对抗搜索 记忆化)

    BZOJ 洛谷P4363 [Update] 19.2.9 重做了遍,感觉之前写的有点扯= = 首先棋子的放置情况是阶梯状的. 其次,无论已经放棋子的格子上哪些是黑棋子哪些是白棋子,之前得分如何,两人在 ...

  4. P2962 [USACO09NOV]灯Lights 对抗搜索

    \(\color{#0066ff}{题目描述}\) 贝希和她的闺密们在她们的牛棚中玩游戏.但是天不从人愿,突然,牛棚的电源跳闸了,所有的灯都被关闭了.贝希是一个很胆小的女生,在伸手不见拇指的无尽的黑暗 ...

  5. 博弈论经典算法(一)——对抗搜索与Alpha-Beta剪枝

    前言 在一些复杂的博弈论题目中,每一轮操作都可能有许多决策,于是就会形成一棵庞大的博弈树. 而有一些博弈论题没有什么规律,针对这样的问题,我们就需要用一些十分玄学的算法. 例如对抗搜索. 对抗搜索简介 ...

  6. 【BZOJ3106】[CQOI2013] 棋盘游戏(对抗搜索)

    点此看题面 大致题意: 在一张\(n*n\)的棋盘上有一枚黑棋子和一枚白棋子.白棋子先移动,然后是黑棋子.白棋子每次可以向上下左右四个方向中任一方向移动一步,黑棋子每次则可以向上下左右四个方向中任一方 ...

  7. P4363 [九省联考2018]一双木棋chess(对抗搜索+记忆化搜索)

    传送门 这对抗搜索是个啥玩意儿…… 首先可以发现每一行的棋子数都不小于下一行,且局面可由每一行的棋子数唯一表示,那么用一个m+1进制数来表示当前局面,用longlong存,开map记忆化搜索 然后时间 ...

  8. ccf 201803-4 棋局评估 (对抗搜索)

    棋局评估 问题描述 Alice和Bob正在玩井字棋游戏. 井字棋游戏的规则很简单:两人轮流往3*3的棋盘中放棋子,Alice放的是“X”,Bob放的是“O”,Alice执先.当同一种棋子占据一行.一列 ...

  9. ICPC Asia Nanning 2017 I. Rake It In (DFS+贪心 或 对抗搜索+Alpha-Beta剪枝)

    题目链接:Rake It In 比赛链接:ICPC Asia Nanning 2017 Description The designers have come up with a new simple ...

随机推荐

  1. android imageview使用的时候 引用资源src和background的区别

    android imageview使用的时候 引用资源时src和background的区别 src更强调内容并且不行拉伸图片进行适配,而background更注重引用图片,会对图片进行拉伸

  2. 数据库——MySQL——数据类型

    详细的看后面给的链接,我只是挑了一部分:http://www.runoob.com/mysql/mysql-data-types.html 在之前说了MySQL的存储引擎.它决定了表的类型,而表内存放 ...

  3. Struts2 第六讲 -- Struts2的结果类型

    7.struts2的结果类型 l 每个 action 方法都将返回一个 String 类型的值, Struts 将根据这个值来决定响应什么结果. l 每个 Action 声明都必须包含有数量足够多的 ...

  4. springboot2.04+mybatis-plus+swagger2+CodeGenerator

    @author zhangyh SpringBoot技术栈搭建个人博客[项目准备]  RESTful API就是一套协议来规范多种形式的前端和同一个后台的交互方式 原型设计 事实上,我是直接先去找的原 ...

  5. SecureCRT 个人使用爱好配置。

    1.设置默认启动会话设置. 2.设置执行 ls命令显示文件夹,各种文件,不同的对比颜色 2.1 设置前: 2.2 设置后: 3. 如果出现会话框中文乱码 ,设置以下选项 4 . 更改 命令 ls -a ...

  6. Swift_数组详解

    Swift_数组详解 点击查看源码 初始化 //初始化 fileprivate func testInit() { //空数组 var array = [Int]() print(array) arr ...

  7. 细说多线程之Thread与Runnable

    1:创建线程的两种方式: 继承Thread类 public class MyThread extends Thread { @Override public void run() { } } MyTh ...

  8. c#数据库连接池

    因为使用习惯的问题,我封装了一个数据库连接池Hikari,这是我自定义的数据库连接池.因为c#的连接池按照规范的ADO.NET里面实现定义的,由数据库官方提供,但是实现方式就不知道了,反正没有看出来, ...

  9. 揭开redux,react-redux的神秘面纱

    16年开始使用react-redux,迄今也已两年多.这时候再来阅读和读懂redux/react-redux源码,虽已没有当初的新鲜感,但依然觉得略有收获.把要点简单写下来,一方面供感兴趣的读者参考, ...

  10. DevOps - 项目构建 - Maven

    Maven介绍Apache Maven是一个创新的软件项目管理和综合工具.Maven提供了一个基于项目对象模型(POM)文件的新概念来管理项目的构建,可以从一个中心资料片管理项目构建,报告和文件.Ma ...