POJ 1321 棋盘问题 C++版

题目链接:http://poj.org/problem?id=1321

题目不解释了,看不懂就没办法了!

我没有用数组储存数据,而是依次用结构体保存每个位置的坐标,因为按顺序输入的,我就没排序了,接下来的就是DFS+回溯,在这些点里取出k个点,且要满足不在同一列上。我利用两个数组来指示行和列是否已被占用,具体见注释把!

PS:这题可以剪枝到0MS,不过可能测试数据松点,暴力DFS就行了!
代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/*Problem: 1321		User: awq123
**Memory: 260K Time: 94MS
**Language: C++ Result: Accepted
*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

struct NODE//坐标保存在结构体数组里
{
int x;
int y;
}map[64];

int c,t,n,k,xused[9],yused[9];//两个指示数组

void DFS(int start,int left)
//start表示判断第几个元素,left表示还要找的数目
{
if(left==0)//如果找完了,计数+1
{
t++;
return;
}
if(start>=c)//超过结构体有效范围
return;
if(xused[map[start].x]==0&&yused;[map[start].y]==0)
//如果这个点满足条件
{
xused[map[start].x]=1;
yused[map[start].y]=1;
//表示已选,搜索下一个
DFS(start+1,left-1);
xused[map[start].x]=0;
yused[map[start].y]=0;
//回溯
}
DFS(start+1,left);
return;
}

int main()
{
int i,j;
while(cin>>n>>k&&n;+k+2)
{
c=0;
t=0;
memset(xused,0,sizeof(xused));
memset(yused,0,sizeof(yused));
//初始化指示数组
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
{
char temp;
cin>>temp;
if(temp=='#')
{
map[cpp].x=i;
map[cpp].y=j;
c++;
}
}
}
DFS(0,k);//由第0个开始找k个
cout<<t<<endl;
}
}