棋盘问题 POJ 1321 | 搜索 | dfs

传送门:POJ1321
首先注意POJ不认<bits/stdc++.h>…orz CE一发。
这道题最开始搜索搜的很混乱,看了八皇后再回来写。写棋盘搜索还是要先考虑剪枝,不是是棋盘搜索就一定dfs(int x, int y)这样搜的。比如八皇后和这道题,既然已知每行只有一个棋子,其实就可以只把行设为参数dfs(int row),不但会简化问题,写起来也不会头晕(省下了step部分的一坨……)。

我们在每次操作的时候要判断的其实只有两点(行固定的情况下):

  • 该位置是否是’#’,即是否可以放棋子(在读入棋盘的时候就进行判断,更新available[][]数组)
  • 行固定的情况下判断该列是否已经有棋子(通过colmark[]数组)

那么还有一个问题,因为N皇后问题那里是给我们N*N棋盘放N个棋子,所以每一行必然都会有一个棋子。但是,这道题不一定,很可能出现有10行但是只要放3个棋子的情况;并且还有可能我们虽然这一行不能放(均为’.’),但是因为行数远远多于要求棋子的数目,所以可以在后面的行中放棋子。也就是说,八皇后里面我们的判断和dfs是在一起的,但是这里判断成功后dfs,判断不成功其实也要dfs!!不然是没法扫完全的。

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

#define ll long long

int n, k, ans;//n <= 8 k <= n
//ll ans;
char matrix[10][10], available[10][10], colmark[10];

void dfs(int row, int rest)
{
    //printf("row = %d  rest = %d\n", row, rest);
    if(rest == 0)
    {
        ans++;
        return;
    }
    if(row == n+1)
        return;

    for(int i = 1;i <= n;i++)
    {
        if(colmark[i] == 0)
        {
            //printf("colmark[%d] = %d\n", i, colmark[i]);
            //printf("available[%d][%d] = %d\n", i, row, available[i][row]);
            if(available[i][row])
            {
                colmark[i] = 1;
                //printf("dfs row = %d rest = %d\n", row+1, rest-1);
                dfs(row+1, rest-1);
                colmark[i] = 0;
            }
        }
    }
    dfs(row+1, rest);
    /**加粗部分对应的就是这里!判断不成功也要dfs!只是我们没有放棋子,所以剩余棋子的数量不减少罢了**/

}


//任意的两个棋子不能放在棋盘中的同一行或者同一列
int main()
{
    while(scanf("%d %d", &n, &k) && n!=-1 && k!=-1)
    {

        memset(available, 0, sizeof(available));

        for(int i = 1;i <= n;i++)
        {
            getchar();
            for(int j = 1;j <= n;j++)
            {
                scanf("%c", &matrix[i][j]);
                if(matrix[i][j] == '#')
                    available[i][j] = 1;
            }
        }

        ans = 0;
        memset(colmark, 0, sizeof(colmark));
        dfs(1, k);

        printf("%d\n", ans);
    }
    return 0;
}

最开始忘记memset available了……WA了,以为是ans的问题(2^31 略略超过10^9),不过后来又试了试用int也可以过。
抄在小本本上:

  • 231 int合法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值