POJ_1321 棋盘问题

本文探讨了一个关于在n*n的棋盘上放置棋子的问题,要求每行每列只能放置一颗棋子,并求出所有可能的放置方法数量。通过深度优先搜索与回溯的方法来解决这一挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接

题目意思

给你一个n*n的棋盘,让你往上边放k颗棋子,要求每一行或者每一列只能有一颗棋子出现,问你最多有几种方法放置棋子。其中#代表棋盘区域。

解题思路

这道题类似于n皇后问题,主要思想就是深搜加回溯。要找到#,你可以放置棋子也可以不放棋子,但是要求的每行每列都只能有一个棋子,如果放置棋子,就要回溯到原点接着搜索,如果搜到了最后也要回溯,具体看代码

代码部分

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int n,k,ans;
char mp[10][10];
bool judge(int x,int y)
{
    for(int i=x-1; i>=0; i--) ///判断同一列有没有放过
    {
        if(mp[i][y]=='*')
            return false;
    }

    for(int j=y-1; j>=0; j--) ///判断同一行有没有放过
    {
        if(mp[x][j]=='*')
            return false;
    }
    return true;
}

void dfs(int cur,int s)///cur 为当前点,s为放置了多少个棋子
{
    if(s==k)///当达到要求的时候就停止
    {
        ans++;
        return ;
    }
    if(cur==n*n)///当走到头的时候停止
    {
        return ;
    }

    int i=cur/n;   //得出来的i,j为当前cur的坐标
    int j=cur%n;

    if(mp[i][j]=='#'&&judge(i,j))//只有当前点可以放置棋子并且同行同列没有棋子的时候,才可以选择是否在这个地方放置棋子
    {
        mp[i][j]='*';
        dfs(cur+1,s+1);//放置棋子
        mp[i][j]='#';
    }
    dfs(cur+1,s);//不放棋子
}
int main()
{
    while(cin>>n>>k)
    {
        ans=0;
        if(n==-1&&k==-1)
            break;
        for(int i=0; i<n; i++)
            scanf(" %s",mp[i]);//在%s之前加空格可以防止数组读取回车
        dfs(0,0);
        cout<<ans<<endl;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值