-1

https://www.hackerrank.com/challenges/chessboard-game-again-1

我以以下方式尝试了上述问题,但答案被评估为错误。(我不是在寻求解决方案,而是在寻求方法中的缺陷);

我的代码(请忽略 c99 错误)

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int numofmov = 0;
int issafe(int a,int b){
    if(a>=0 && a<15 && b>=0 && b<15)
        return 1;
    return 0;
}
void move(int board[][15]){
    for(int i=0;i<15;i++){
        for(int j=0;j<15;j++){
            if(board[i][j]>0){
                board[i][j]--;
                if(issafe(board,i-2,j+1)==1) {
                    numofmov++;
                    board[i-2][j+1]++;
                }
                if(issafe(board,i-2,j-1)==1) {
                    numofmov++;
                    board[i-2][j-1]++;
                }                
                if(issafe(board,i+1,j-2)==1) {
                    numofmov++;
                    board[i+1][j-2]++;
                }
                if(issafe(board,i-1,j-2)==1) {
                    numofmov++;
                    board[i-1][j-2]++;
                }
            }
        }
    }
}
int main() {

    /* Enter your code here. Read input from STDIN. Print output to STDOUT */  
    int t;
    scanf("%d",&t);
    while(t--){
        int k;
        scanf("%d",&k);
        int board[15][15];
        for(int j=0;j<15;j++){
            for(int h=0;h<15;h++){
                board[j][h]=0;
            }
        }
        for(int i=0;i<k;i++){
            int x,y;
            scanf("%d %d",&x,&y);
            board[x-1][y-1]++;
        }
        int bro=0,mov=numofmov;
        while(bro==0){
            move(board);
            if(numofmov==mov){
                bro++;
                printf("Second\n");
                break;
            }
            mov = numofmov;
            move(board);
            if(numofmov==mov){
                bro++;
                printf("First\n");
                break;
            }
            mov = numofmov;
        }
    }
    return 0;
}

我的方法是继续使所有硬币的所有移动都成为可能,直到我们到达无法移动的地步。但这在某些测试用例中给出了错误的答案。

4

1 回答 1

3

您在问这种方法有什么问题?

“我的方法是继续使所有硬币的所有移动都成为可能,直到我们达到无法移动的地步。但这在某些测试用例中给出了错误的答案。”

我没有阅读您的代码,但我可以说主要问题是您的方法本身。你认为这个问题是一种蛮力(让所有可能的移动路径,看看谁赢了)。可能的移动数量可以任意大,检查导致获胜的移动是无限慢的。实际上,它要么是动态规划,要么是更相关的博弈论问题。这样想吧。起始位置是否唯一标识了这场比赛的获胜者?如果我改变一个硬币的初始位置,获胜者也会改变吗?

解决此类问题的最佳方法是简化它。假设只有一个棋盘有一个硬币,位于(x,y)。现在请注意,在一枚硬币从一个位置移动到另一个(x,y)位置(a,b)之后,以下情况是正确的a+b<x+y。因此,如果(x,y)是其中之一(1,1),(1,2),(2,1),(2,2),则采取行动的玩家已经输了。所以我的目标是确保我的对手从已经失去的位置开始行动,如果我能做到,我就处于胜利的位置。如果您遵循相同的逻辑,您将意识到这种方法将唯一地识别位置是赢还是输。因此,对于任何位置,我们都可以回答它是赢还是输,只需通过从(1,1)到倒退来构建答案网格(15,15)

现在如果板的数量超过一个,你会怎么做?你需要深入研究博弈论,特别是Grundy数字以及它们与Nim游戏的关系。我建议您查看以下链接以获取更多信息:

https://en.wikipedia.org/wiki/Nim

https://en.wikipedia.org/wiki/Nimber

https://www.topcoder.com/community/data-science/data-science-tutorials/algorithm-games/

于 2016-07-19T08:18:11.947 回答