Xtreme 10.0 - Checkers Challenge

這是 meelo 原創(chuàng)的 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.

題目解析
這題是一個搜索題逸雹,用深度優(yōu)先搜索可以解決云挟。
題目中的游戲規(guī)則比較復(fù)雜园欣,一定要仔細閱讀。最初沒有注意到日矫,普通白子不能向下走,浪費了很多時間盈魁。
使用回溯法可以避免保存狀態(tài)窃诉。

程序
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 原創(chuàng)敦冬,請務(wù)必以鏈接形式注明 本文地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末脖旱,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子萌庆,更是在濱河造成了極大的恐慌践险,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件彭则,死亡現(xiàn)場離奇詭異俯抖,居然都是意外死亡瓦胎,警方通過查閱死者的電腦和手機搔啊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瓶盛,“玉大人,你說我怎么就攤上這事≡浚” “怎么了绍绘?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵陪拘,是天一觀的道長。 經(jīng)常有香客問我捺信,道長欠痴,這世上最難降的妖魔是什么喇辽? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮吠式,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抽米。我一直安慰自己特占,他們只是感情好,可當我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布缨硝。 她就那樣靜靜地躺著摩钙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪查辩。 梳的紋絲不亂的頭發(fā)上胖笛,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機與錄音宜岛,去河邊找鬼长踊。 笑死,一個胖子當著我的面吹牛身弊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼阱佛,長吁一口氣:“原來是場噩夢啊……” “哼帖汞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起凑术,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤翩蘸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后淮逊,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體催首,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年泄鹏,在試婚紗的時候發(fā)現(xiàn)自己被綠了郎任。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡备籽,死狀恐怖舶治,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情胶台,我是刑警寧澤歼疮,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站诈唬,受9級特大地震影響韩脏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜铸磅,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一赡矢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧阅仔,春花似錦吹散、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至羞迷,卻和暖如春界轩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背衔瓮。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工浊猾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人热鞍。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓葫慎,卻偏偏與公主長得像衔彻,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子偷办,可洞房花燭夜當晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容