POJ1321 棋盘问题

题目大意:
题目为中文,见http://poj.org/problem?id=1321

思路:
看到这个题,我最容易联想到八皇后问题。我认为本题与八皇后问题唯一不同的一点在于八皇后问题每一行必定会放一个棋子,而本题中有的行可能不需要放棋子。与八皇后思路相同,本题也采用深度优先搜索,对每一行进行深度优先搜索,要注意不放皇后的情况。

代码如下:

#include <iostream>

using namespace std;

#define MAXNUM 10

int counter = 0;
int res[MAXNUM];            //第i行放棋子在第res[i]列,不放置为-1
char data[MAXNUM][MAXNUM];

bool canplace(int row,int col);
void DFS(int row,int num,int n,int k);

int main()
{
    int n = 0;
    int k = 0;
    while(true)
    {
        counter = 0;                   //初始化
        memset(data, 0, sizeof(data));
        memset(res,100,sizeof(res));
        for(int i = 0; i < MAXNUM; i++)
        {
            res[i] = -1;
        }

        cin>>n>>k;
        if(n == -1 && k == -1)
        {
            break;
        }
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < n; j++)
            {
                cin>>data[i][j];
            }
        }

        DFS(0,0,n,k);    //按行进行深搜
        cout<<counter<<endl;
    }
    return 0;
}

void DFS(int row,int num,int n,int k)
{
    //当前搜索第row行,共放了num个棋子
    if(num == k)
    {
        counter++;
        return;
    }
    if(row >= n)
    {
        return;
    }
    else
    {
        for(int j = 0; j < n; j++)    //对每一列进行判断
        {
            if(canplace(row,j))
            {
                res[row] = j;
                DFS(row + 1,num + 1,n,k);
                res[row] = -1;
            }
        }
        DFS(row + 1,num,n,k);         //注意这一行不放棋子的情况
    }
}

bool canplace(int row,int col)
{
    //判断在row行,col列可不可以放棋子
    int i = 0;
    bool flag = false;
    if(data[row][col] != '#')     //当前行列不是棋盘,不能放
    {
        flag = false;
    }
    else
    {
        for(i = 0; i < row; i++)
        {
            if(res[i] == col)      //当前列已经放了棋子,不能再放
            {
                flag = false;
                break;
            }
        }
        if(i == row)
        {
            flag = true;
        }
    }
    return flag;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值