URAL 1216 Two Pawns and One King

来源:互联网 发布:淘宝隐藏优惠券骗局 编辑:程序博客网 时间:2024/05/22 03:21

题意

n*n的棋盘中,有三个国际象棋棋子,分别是黑王,黑兵,白兵。
规定:
如果白兵到底线升变,白方胜
如果黑王被吃,白方胜
如果黑兵到达底线,可以升变。
如果白兵无法移动或被吃,黑方胜。
王、兵移动规则与吃子规则完全模仿国际象棋
问:残局下,谁胜

题解

坑比题。
不计其数的卡,比如王卡象,王卡兵,王卡车,另外还有兵卡王。
注意过路兵这个设定是存在的
比较恶心的在于,白兵可以选择不吃黑兵,直接向前。。。
如果想要少考虑些,可以思考写成DP
但DP也难写,更重要的一点是:白方是具有决策的,而且是有两种:开始走两步以及吃与不吃
剩下的就是一个BFS了

code

#include <algorithm>#include <bitset>#include <cassert>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <ctime>#include <deque>#include <iostream>#include <map>#include <queue>#include <set>#include <string>#include <vector>typedef long long LL;const int dxy[8][2] = {{1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}, {0, -1}, {1, -1}};const int maxn = 30;const int maxQ = 6000010;int n;struct Point {    char x, y;};struct Node {    Point wp, bp, bk; bool col;};Point wp, bp, bk;Point _wp, _bp, _bk;Node Q[maxQ]; int l, r;bool check(int x, int y) { return 1 <= x && x <= n && 1 <= y && y <= n; }std::set<LL> inq;LL encode(const Node& A) {    return ((((((LL)A.wp.x*30+A.wp.y)*30+A.bp.x)*30+A.bp.y)*30+A.bk.x)*30+A.bk.y)*2 + A.col;}void push_Q(const Node& A) {    int x = encode(A);    if (inq.count(x)) return;    inq.insert(x);    Q[r ++] = A; if (r == maxQ) r = 0;}bool white(bool eat, bool fly) {    l = r = 0; inq.clear();    push_Q((Node){_wp, _bp, _bk, 0});    for (; l != r; l = (l+1 == maxQ ? 0 : l+1)) {        Node u = Q[l]; wp = u.wp, bp = u.bp, bk = u.bk;//      printf("%d %d %d %d %d %d\n", wp.x, wp.y, bp.x, bp.y, bk.x, bk.y);        if (u.wp.y == n) continue;        if (u.col == 0) {            if (std::abs(bk.x-wp.x) == 1 && bk.y == wp.y + 1) continue;            if (fly && wp.y == 2) {                if (!(bp.x == wp.x && bp.y == wp.y+1) && !(bk.x == wp.x && bk.y == wp.y+1)) {                    if (!(bp.x == wp.x && bp.y == wp.y+2) && !(bk.x == wp.x && bk.y == wp.y+2) && !(std::abs(bp.x-wp.x) == 1 && bp.y == wp.y+2)) {                        wp.y += 2; push_Q((Node){wp, bp, bk, 1}); wp.y -= 2;                        continue;                    }                } else                    return 0;            }            if (eat && std::abs(bp.x-wp.x) == 1 && bp.y == wp.y + 1) {  push_Q((Node){(Point){bp.x, bp.y}, (Point){-1, -1}, bk, 1}); continue; }            if (!(bp.x == wp.x && bp.y == wp.y+1) && !(bk.x == wp.x && bk.y == wp.y+1)) {                ++ wp.y; push_Q((Node){wp, bp, bk, 1}); -- wp.y;            } else                return 0;        } else {            if (bp.x != -1) {                if (bp.y == 1) {                    if (wp.y+1 < n) {  return 0; }                    if ((wp.x == bp.x+1 && wp.y == bp.y+2) || (wp.x == bp.x+2 && wp.y == bp.y+1) ||                        (wp.x == bp.x-1 && wp.y == bp.y+2) || (wp.x == bp.x-2 && wp.y == bp.y+1)) { return 0; }                    if (wp.x == bp.x && !(bk.x == bp.x && bp.y <= bk.y && bk.y <= wp.y))                        return 0;                    if (wp.x < bp.x && !(bk.y-bp.y == bp.x-bk.x) && (wp.y <= bp.y + (bp.x-wp.x))) return 0;                    if (wp.x > bp.y && !(bk.y-bp.y == bk.x-bp.x) && (wp.y <= bp.y + (wp.x-bp.x))) return 0;                } else {                    if (std::abs(wp.x-bp.x) == 1 && wp.y == bp.y-1) { return 0; }                    if (!(wp.x == bp.x && wp.y == bp.y-1) && !(bk.x == bp.x && bk.y == bp.y-1)) {                        if ((wp.x != bp.x || wp.y != bp.y-2) && bp.y == n-1 && !(std::abs(wp.x-bp.x) == 1 && wp.y == bp.y-2)) { bp.y -= 2; push_Q((Node){wp, bp, bk, 0}); bp.y += 2; }                        -- bp.y; push_Q((Node){wp, bp, bk, 0}); ++ bp.y;                    }                }            }            if (std::abs(wp.x-bk.x) <= 1 && std::abs(wp.y-bk.y) <= 1) { return 0; }            for (int d = 0; d < 8; ++ d) {                int X = bk.x + dxy[d][0], Y = bk.y + dxy[d][1];                if (!(bp.x == X && bp.y == Y) && check(X, Y)) { push_Q((Node){wp, bp, (Point){X, Y}, 0}); }            }        }    }    return 1;}void solve() {    int t1, t2, t3;     scanf("%d %c%d %c%d %c%d", &n, &wp.x, &t1, &bp.x, &t2, &bk.x, &t3);    wp.x -= 'a'-1; bp.x -= 'a'-1; bk.x -= 'a'-1;    wp.y = t1, bp.y = t2, bk.y = t3;    _wp = wp; _bp = bp; _bk = bk;//  printf("%d\n", white(1, 1));//  printf("%d\n", white(1, 0));//  printf("%d\n", white(0, 1));//  printf("%d\n", white(0, 0));    if (white(1, 1) || white(1, 0) || white(0, 1) || white(0, 0)) puts("WHITE WINS"); else puts("BLACK WINS");}int main() {//  freopen("A.in", "r", stdin);//  freopen("A.out", "w", stdout);//  for (int i = 1; i <= 16; ++ i)    solve();//  for(;;);    return 0;}
0 0
原创粉丝点击