您的位置:首页 > 其它

棋盘问题

2017-08-02 19:49 113 查看


棋盘问题


Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 20000/10000K (Java/Other)


Total Submission(s) : 102   Accepted Submission(s) : 33


Problem Description

在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。

 

Input

输入含有多组测试数据。 <br>每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n <br>当为-1 -1时表示输入结束。 <br>随后的n行描述了棋盘的形状:每行有n个字符,
4000
其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。 <br>

 

Output

对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。

 

Sample Input

2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1

 

Sample Output

2
1类似于八皇后问题,以至于没仔细看题,直接敲了个不能在对角线上的由于不是n*n的体盘切方n个棋子,所以套下皇后问题的底子,注意的就是并不是所有的行或者列都有棋子,也就是有时候会出现空白的行或列,这样就需要考虑这一行布放棋子时的情况了也就是无论如何都要跳过这一行一次具体见代码
 /* n皇后问题 */for(i=1;i<=n;i++)  //假设放在第i行
    if(!visit[i])
{
map[k]=i;
flag=1;
for(j=1;j<=k-1;j++)  //以小标为行或列  值为剩下的一个
if((map[k]-map[j])==(k-j)||(map[k]-map[j])==(j-k))  //对角线
{
flag=0;
break;
}
if(flag)
{
visit[i]=1;
dfs(k+1);
visit[i]=0;
}
} 
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
char map[1001][1001];
int vis[1001];
int n,k;
int ans,num;
int dfs(int i){

if(k==num)
{
ans++;
return 0;
}
if(i>=n)
return 0;
for(int j=0;j<n;j++)
{
if(!vis[j]&&map[i][j]=='#')
{
vis[j]=1;
num++;
dfs(i+1);
vis[j]=0;
num--;//回溯
            }
}
dfs(i+1);//注意的就是这里  i行不放棋子 直接i+1行
}
int main(){
int i,j;
char ch;
while(cin>>n>>k)
{
ans=num=0;
memset(map,0,sizeof(map));
memset(vis,0,sizeof(vis));
if(n==-1&&k==-1)break;
//for(i=1;i<=n;i++)
//for(j=1;j<=n;j++)
//{
//cin>>map[i][j];
//}
        for(i=0;i<n;i++)
scanf("%s",&map[i]);
dfs(0);
cout<<ans<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: