回溯和DFS效率分析
回溯和DFS效率分析
一、心得
多组数据记得初始化
两组样例,找圆点点的个数
6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
6 9
....#.
.....#
......
......
...#..
......
......
#@...#
.#..#.
0 0
测试结果
这题用DFS的次数:
45
44
这题用回溯的次数
7 3103 9439 (7亿)
1 5891 4555(1亿)
回溯的次数远高于DFS,
如果题目能用DFS做,就尽量用DFS做
因为DFS是找出一组解,而回溯是找出所有的解
二、题目
http://noi.openjudge.cn/ch0205/1818/
1818:红与黑
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
- 有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻的黑色瓷砖移动。请写一个程序,计算你总共能够到达多少块黑色的瓷砖。
- 输入
- 包括多个数据集合。每个数据集合的第一行是两个整数W和H,分别表示x方向和y方向瓷砖的数量。W和H都不超过20。在接下来的H行中,每行包括W个字符。每个字符表示一块瓷砖的颜色,规则如下
1)‘.’:黑色的瓷砖;
2)‘#’:白色的瓷砖;
3)‘@’:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中唯一出现一次。
当在一行中读入的是两个零时,表示输入结束。 - 输出
- 对每个数据集合,分别输出一行,显示你从初始位置出发能到达的瓷砖数(记数时包括初始位置的瓷砖)。
- 样例输入
-
6 9 ....#. .....# ...... ...... ...... ...... ...... #@...# .#..#. 0 0
- 样例输出
-
45
三、AC代码
1 //1818:红与黑 2 #include <iostream> 3 using namespace std; 4 int width[4]={1,0,-1,0}; 5 int height[4]={0,1,0,-1}; 6 char a[25][25]; 7 int vis[25][25]; 8 int w,h; 9 int w1,h1; 10 int sum; 11 /* 12 6 9 13 ....#. 14 .....# 15 ...... 16 ...... 17 ...... 18 ...... 19 ...... 20 #@...# 21 .#..#. 22 6 9 23 ....#. 24 .....# 25 ...... 26 ...... 27 ...#.. 28 ...... 29 ...... 30 #@...# 31 .#..#. 32 0 0 33 这题用DFS的次数: 34 45 35 44 36 这题用回溯的次数 37 7 3103 9439 (7亿) 38 1 5891 4555(1亿) 39 */ 40 void search(int hh,int ww){ 41 for(int i=0;i<=3;i++){ 42 int h2=hh+height[i]; 43 int w2=ww+width[i]; 44 if(w2>=1&&w2<=w&&h2>=1&&h2<=h&&a[h2][w2]=='.'&&!vis[h2][w2]){ 45 vis[h2][w2]=1; 46 sum++; 47 search(h2,w2); 48 //vis[h2][w2]=0; 49 } 50 } 51 } 52 53 int main(){ 54 freopen("in.txt","r",stdin); 55 while(true){ 56 cin>>w>>h; 57 if(w==0&&h==0) break; 58 sum=1; 59 for(int i=1;i<=h;i++){ 60 for(int j=1;j<=w;j++){ 61 char c1; 62 cin>>c1; 63 if(c1=='@'){ 64 w1=j; 65 h1=i; 66 } 67 a[i][j]=c1; 68 vis[i][j]=0; 69 } 70 } 71 vis[h1][w1]=1; 72 search(h1,w1); 73 74 //cout<<h1<<w1<<endl; 75 //cout<<a[8][2]<<endl; 76 cout<<sum<<endl; 77 } 78 return 0; 79 }