POJ_1321 棋盘问题

来源:互联网 发布:windows临时账户登录 编辑:程序博客网 时间:2024/06/04 18:29

题目链接

题目意思

给你一个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;    }}
原创粉丝点击