Xtreme 10.0 - Checkers Challenge

这是 meelo 原创的 IEEEXtreme极限编程大赛题解

Xtreme 10.0 - Checkers Challenge
题目来源 第10届IEEE极限编程大赛
https://www.hackerrank.com/contests/ieeextreme-challenges/challenges/draughts-1

Watch the following YouTube video clip. Your task is to compute the number of possible ways the white player can win from an opening state of a single white piece in a game of Turkish Draughts. For more information on the game, you can view the Wikipedia page.
For this challenge, we will use the following variation on the official rules:
The black pieces can be arbitrary placed, and will not necessarily be located at places reachable in a legal game

  1. A single white piece is a king if, and only if, it is placed in or reaches the top most line. Once a piece is a king it remains a king throughout.
  2. A white piece can capture by jumping over a single black piece to the left, right or upwards, landing in the adjacent square
  3. A white king can capture by jumping left, right, upwards or backwards and can skip arbitrary number of blank squares before and after the black piece
  4. After capturing a black piece, the white piece (or king) must turn 90 degrees or keep moving in the same direction (no 180 degree turns are allowed).
  5. We ask for the number of different ways the white player can win a single move. White wins by capturing all black pieces.

Input Format

Each input begins with an integer t, on a line by itself, indicating how many testcases are present.
Each testcase will contain 8 lines with the state of the board. The board will have a single white piece o, some black pieces x, and empty places .. White's side of the board is at the bottom of the board. So if the white piece were to reach to top row of the board, it would become a king.
In between each testcase is a blank line.

Constraints

1 ≤ t ≤ 5
There will always be at least 1, and no more than 16, black pieces in each game.
The game board will always be 8x8 squares in size.

Output Format

For each testcase, output, on a line by itself, the number of possible ways the white can win, or 0
if he cannot.

Sample Input

3
.......o
.x.x.x..
xxxx.xx.
........
........
.x.xx..x
x.......
..x...x.

........
........
....o...
........
....x...
........
........
........

...o....
........
...x....
........
........
........
........

Sample Output

1205

Explanation

The first testcase is the state of the board in the 56th second of the YouTube video. There are 12 ways in which this game can be won. These ways are represented below:
down 7, left 3, up 6, left 2, down 4, right 4, up 4, left 3, down 4, left 3, up 4, right 5, down 6, left 5, up 5, right 2
down 7, left 3, up 6, left 2, down 4, right 4, up 4, left 3, down 4, left 3, up 4, right 5, down 6, left 5, up 5, right 3
down 7, left 3, up 6, left 2, down 4, right 4, up 4, left 3, down 4, left 3, up 4, right 5, down 6, left 5, up 5, right 4
down 7, left 3, up 6, left 2, down 4, right 4, up 4, left 3, down 4, left 3, up 4, right 5, down 6, left 5, up 5, right 5
down 7, left 3, up 6, left 2, down 4, right 4, up 4, left 3, down 4, left 3, up 4, right 5, down 6, left 5, up 5, right 6
down 7, left 3, up 6, left 2, down 4, right 4, up 4, left 3, down 4, left 3, up 4, right 5, down 6, left 5, up 5, right 7
down 7, left 3, up 6, right 2, down 4, left 4, up 4, right 3, down 4, left 5, up 4, right 3, down 6, left 3, up 5, right 2
down 7, left 3, up 6, right 2, down 4, left 4, up 4, right 3, down 4, left 5, up 4, right 3, down 6, left 3, up 5, right 3
down 7, left 3, up 6, right 2, down 4, left 4, up 4, right 3, down 4, left 5, up 4, right 3, down 6, left 3, up 5, right 4
down 7, left 3, up 6, right 2, down 4, left 4, up 4, right 3, down 4, left 5, up 4, right 3, down 6, left 3, up 5, right 5
down 7, left 3, up 6, right 2, down 4, left 4, up 4, right 3, down 4, left 5, up 4, right 3, down 6, left 3, up 5, right 6
down 7, left 3, up 6, right 2, down 4, left 4, up 4, right 3, down 4, left 5, up 4, right 3, down 6, left 3, up 5, right 7

There is no way for white to win the second testcase.
For the final testcase, white has a king, and white can capture the single black piece, and land on any of the five spaces below the piece.

题目解析
这题是一个搜索题,用深度优先搜索可以解决。
题目中的游戏规则比较复杂,一定要仔细阅读。最初没有注意到,普通白子不能向下走,浪费了很多时间。
使用回溯法可以避免保存状态。

程序
C++

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

bool legal(int x, int y) {
    return (x>=0) && (x<8) && (y>=0) && (y<8);
}

int countWin(char board[8][8], bool isKing, int wx, int wy, int lastDir, int numBlack) {
    int count = 0;
    
    // game over
    if(numBlack == 0) return 1;
    
    int dir[4][2] = { {0,1}, {0,-1}, {-1,0}, {1,0} };
    int bx, by; // black piece to the left, right or upwards
    int sx, sy; // landing square
    
    if(!isKing) {
        // cannot go downwards, possible directions: 0, 1, 2
        for(int d=0; d<3; d++) {
            
            bx = wx + dir[d][0];
            by = wy + dir[d][1];
            sx = wx + dir[d][0] * 2;
            sy = wy + dir[d][1] * 2;
            
            if(board[bx][by]=='x' && legal(sx, sy) && board[sx][sy]=='.') {
                if(sx == 0) isKing = true;
                board[bx][by] = '.';
                numBlack--;
                count += countWin(board, isKing, sx, sy, d, numBlack);
                // backtrack
                board[bx][by] = 'x';
                numBlack++;
            }
        }
    }
    else {
        for(int d=0; d<4; d++) {
            if((d==0 && lastDir==1) || (d==1 && lastDir==0) || 
            (d==2 && lastDir==3) || (d==3 && lastDir==2)) {
                continue;
            }
            bx = by = -1;
            // white king can go at least 1 step, at most 6 steps
            for(int skipBefore=1; skipBefore<=6; skipBefore++) {
                int tx = wx + dir[d][0] * skipBefore;
                int ty = wy + dir[d][1] * skipBefore;
                if(legal(tx, ty) && board[tx][ty]=='x') {
                    bx = tx;
                    by = ty;
                    break;
                }
            }
            //cout << bx << ' ' << by << endl;
            if(!legal(bx, by)) continue;
            for(int skipAfter=1; skipAfter<=6; skipAfter++) {
                int tx = bx + dir[d][0] * skipAfter;
                int ty = by + dir[d][1] * skipAfter;
                if(legal(tx, ty) && board[tx][ty]=='.') {
                    board[bx][by] = '.';
                    numBlack--;
                    int C = countWin(board, isKing, tx, ty, d, numBlack);
                    count += C;
                    // backtrack
                    board[bx][by] = 'x';
                    numBlack++;
                }
                else {
                    break;
                }
                
            }
        }
    }

    return count;
}


int main() {
    /* Enter your code here. Read input from STDIN. Print output to STDOUT */   
    int T;
    cin >> T;
    for(int t=0; t<T; t++) {
        char board[8][8];
        for(int l=0; l<8; l++) {
            cin >> board[l];
        }
        
        // check whether is king or not
        bool isKing = false;
        for(int c=0; c<8; c++) {
            if(board[0][c] == 'o') isKing = true;
        }
        
        // locate white piece
        int wx, wy, numBlack = 0;
        for(int l=0; l<8; l++) {
            for(int c=0; c<8; c++) {
                if(board[l][c] == 'o') {
                    wx = l;
                    wy = c;
                    board[l][c] = '.';
                }
                else if(board[l][c] == 'x') {
                    numBlack++;
                }
            }
        }
        cout << countWin(board, isKing, wx, wy, -1, numBlack) << endl;
        getchar();
    }
    return 0;
}

博客中的文章均为 meelo 原创,请务必以链接形式注明 本文地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,919评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,567评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,316评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,294评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,318评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,245评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,120评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,964评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,376评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,592评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,764评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,460评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,070评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,697评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,846评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,819评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,665评论 2 354

推荐阅读更多精彩内容