POJ1321-棋盘问题 简单搜索DFS

https://vjudge.net/contest/65959#problem

A题POJ1321

题目类型:DFS类型题目

难易程度:1

被吊打的老年选手,现在连字符串图的读入都有点问题了。不过多写几下就好了。

思路:

DFS的参数是 当前遍历到的层数 和 当前放置的棋子的个数。

用一个标记数组来标记当前列有没有被访问过。

DFS具体过程,对当前行的每一列进行判断(看当前位置是否是棋盘,当前位置是否被标记过),如果是棋盘,且没有被标记过,那么就将当前列标记,并进入下一行进行DFS(row+1,num+1)。(DFS前后要对放置棋子的个数进行标记和取消标记)。

当对整行都遍历了之后,再 DFS(row+1,num),跨过当前行用下一行。

DFS的出口是:当num == k(即放置的棋子数到达要求的棋子数时,停止。还有就是当访问的行row 越界后,也停止)

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

char c;
int  n, k;
int vis_col[10];
int g[10][10];
int ans = 0;

void DFS(int row, int num)
{
    if(num == k)
    {
        ans ++;
        return;
    }
    if (row >= n)
        return;

    for(int icol = 0; icol < n; ++icol)
    {
        if(g[row][icol] && !vis_col[icol])
        {
            vis_col[icol] = 1;
                DFS(row+1, num+1);
            vis_col[icol] = 0;
        }
    }

    DFS(row+1, num);
}

int main()
{
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);

    while(scanf("%d %d", &n, &k) != EOF && n!=-1 && k!=-1)
    {
        memset(g, 0, sizeof(g));
        ans = 0;
        memset(vis_col, 0, sizeof(vis_col));
        for(int i = 0; i < n; ++i)
        {
            for(int j = 0; j < n; ++j)
            {
                cin >> c;
                if(c == '#')
                    g[i][j] = 1;
            }
        }


        DFS(0,0);
        printf("%d
", ans);

    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/ya-cpp/p/8245550.html