题目:
棋盘问题
Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u
Description
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,
请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
Input
输入含有多组测试数据。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
Output
对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
Sample Input
2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1
Sample Output
2
1
题目大意:
给n*n大小的图,其中#是能放棋子的地方,求放k个棋子有多少种方法。
题目思路:
因为要求多少种方法,且前后相互关联。所以用dfs来求
程序:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
#include<stack>
using namespace std;
struct la
{
int x,y,t;
} a;
bool v[10][10];
char s[10][10];
int q[10],p[10];
int main()
{
int n,m,i,j,k,da,x,y,t;
stack<la>st;
while(~scanf("%d %d",&n,&m))
{
if(n==-1&&m==-1)
break;
da=0;
while(!st.empty())
st.pop();
memset(q,0,sizeof(q));
memset(p,0,sizeof(p));
memset(v,0,sizeof(v));
for(i=1; i<=n; i++)
scanf("%s",s[i]+1);
a.x=0,a.y=0,a.t=0;
st.push(a);
while(!st.empty())
{
a=st.top();
x=a.x,y=a.y,t=a.t;
if(t==m)
{
st.pop();
p[x]=0;
q[y]=0;
da++;
//cout<<'!'<<x<<'!'<<y<<endl;
v[x][y]=0;
continue;
}
if(v[x][y])
{
st.pop();
p[x]=0;
q[y]=0;
v[x][y]=0;
continue;
}
else
{
v[x][y]=1;
p[x]=1;
q[y]=1;
}
for(i=x+1; i<=n; i++)
{
if(!p[i])
for(j=1; j<=n; j++)
{
if(!q[j]&&s[i][j]=='#')
{
a.x=i;
a.y=j;
a.t=t+1;
st.push(a);
}
}
}
}
printf("%d\n",da);
}
return 0;
}