poj1970 The Game(DFS)

题目链接

http://poj.org/problem?id=1970

思路

题目的意思是判断五子棋棋局是否有胜者,有的话输出胜者的棋子类型,并且输出五个棋子中最左上的棋子坐标;没有胜者输出0.
这道题目是floodfill延伸而来,使用dfs求解,但这道题比普通的floodfill题目又多了一些难度,比如要输出最左上棋子的坐标,我的做法是在main函数中从上到下、从左到右遍历棋盘,当位置(r, c)有棋子时,则从该位置开始dfs,加上搜索的方向为向右(r, c+1),向下(r+1, c),右下(r+1, c+1),右上(r, c-1),所以如果搜索的结果符合获胜的条件,则(r, c)就为最左上的位置。普通dfs题目标记是否搜索过时大多使用二维数据visit[i][j],在该题中,除了坐标之外,还要加上方向vist[i][j][d],表示在坐标(i, j)的d方向是否搜索过。

代码

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int N = 19;
int board[N+1][N+1];
int visit[N+1][N+1][4];
int dir[4][2] = {{-1, 1}, {0, 1}, {1, 1}, {1, 0}};  //方向为右上、右、右下、下
int cnt;

void dfs(int r, int c, int d, int type){
    visit[r][c][d] = 1;
    int nr = r + dir[d][0];
    int nc = c + dir[d][1];

    if(nr>=0 && nr<N && nc>=0 && nc<N && board[nr][nc]==type){  //注意这里不需要条件 && !visit[nr][nc][d]
        cnt++;
        dfs(nr, nc, d, type);
    }
}

int main(){
    //freopen("poj1970.txt", "r", stdin);
    int t;
    cin>>t;
    while(t--){
        memset(board, 0, sizeof(board));
        memset(visit, 0, sizeof(visit));
        for(int i=0; i<N; i++){
            for(int j=0; j<N; j++){
                scanf("%d", &board[i][j]);
            }
        }

        bool win = false;
        for(int i=0; i<N; i++){
            for(int j=0; j<N; j++){
                if(board[i][j]){
                    int type = board[i][j];
                    for(int k=0; k<4; k++){
                        if(!visit[i][j][k]){
                            cnt = 1;
                            dfs(i, j, k, type);
                            if(cnt==5 && board[i-dir[k][0]][j-dir[k][1]]!=board[i][j]){    //排除6子连珠的情况
                                win = true;
                                printf("%d\n%d %d\n", type, i+1, j+1);
                            }
                        }
                        if(win) break;
                    }
                }
                if(win) break;
            }
            if(win) break;
        }
        if(!win){
            cout<<"0"<<endl;
        }
    }
    return 0;
}

posted @ 2017-11-03 16:53  ColdCode  阅读(322)  评论(0编辑  收藏  举报
AmazingCounters.com