POJ1321-Chess Problem
大致题意:
中文题。。我没什么好说的
解题思路:
DFS,没想法就很难很难,有想法就很容易的题
棋盘规则与否不是难点,无论规则不规则都可以用标记去解决
难点在于 棋盘的行数(列数)n 与 待摆放的棋子总数k 的关系为k<=n
K==n时还是比较好办的
K<n时就让人有点迷糊不知怎样处理了
网上普遍做法都是 逐行深搜,效率不错,我也稍微借鉴了,具体看程序,不多说了,搜索的题抽象性太强,文字很难说清楚
1 //Memory Time
2 //184K 32MS
3
4 #include<iostream>
5 using namespace std;
6
7 bool chess[9][9];
8 bool vist_col[9]; //列标记
9 int status; //状态计数器
10 int n,k;
11
12 void DFS(int row,int num) //逐行搜索,row为当前搜索行,num为已填充的棋子数
13 {
14 if(num==k)
15 {
16 status++;
17 return;
18 }
19
20 if(row>n) //配合下面DFS(row+1,num); 语句使用,避免搜索越界
21 return;
22
23 for(int j=1;j<=n;j++)
24 if(chess[row][j] && !vist_col[j])
25 {
26 vist_col[j]=true; //放置棋子的列标记
27 DFS(row+1,num+1);
28 vist_col[j]=false; //回溯后,说明摆好棋子的状态已记录,当前的列标记还原
29 }
30
31 DFS(row+1,num); //这里是难点,当k<n时,row在等于n之前就可能已经把全部棋子放好
32 //又由于当全部棋子都放好后的某个棋盘状态已经在前面循环时记录了
33 //因此为了处理多余行,令当前位置先不放棋子,搜索在下一行放棋子的情况
34 return;
35 }
36
37 int main(int i,int j)
38 {
39 while(cin>>n>>k)
40 {
41 if(n==-1 && k==-1)
42 break;
43
44 /*Initial*/
45
46 memset(chess,false,sizeof(chess));
47 memset(vist_col,false,sizeof(vist_col));
48 status=0;
49
50 for(i=1;i<=n;i++)
51 for(j=1;j<=n;j++)
52 {
53 char temp;
54 cin>>temp;
55 if(temp=='#')
56 chess[i][j]=true;
57 }
58
59 DFS(1,0); //注意初始化的值别弄错了
60 cout<<status<<endl;
61 }
62 return 0;
63 }
[ EXP技术分享博客 ] 版权所有,转载请注明出处: http://exp-blog.com