第六章学习小结
一、本章学习心得
如图为第六章的思维导图,首先要掌握图的定义和基本术语,理解好后才能进行深入的学习。比较重要的部分是图的存储结构和图的遍历,图的遍历包括深搜和广搜。顾名思义,深搜是一条路走到头,没走过的路继续走,而广搜的含义则是每条路都兼顾(邻接点)。图的应用中,最小生成树的绘制过程比较重要。
二、拯救007
做这道题首先要读懂题目
- 题目要求是以(0,0)为坐标原点,建立直角坐标系,其中,原点是鳄鱼池的中心,以原点为中心,有一个半径为7.5的圆。
- 在圆外有N个坐标点,分别是每个鳄鱼的坐标。
- 首先,007要成功跳跃第一步,如果第一步的最大距离都无法满足从岛的边缘跳到鳄鱼头,那么肯定是失败的。
- 如果007从岛的边缘直接跳到岸边,也就是D>=42.5米,那么也是成功的。
- 能否从一个鳄鱼头跳到另一个鳄鱼头,应当使最大距离的平方大于两鳄鱼头距离的平方。
- 判断能否成功跳跃到池外的条件是,所在坐标点的横纵坐标加减最大跳跃距离后可以大于50或小于-50。
- 建立Node存储结构,并使用深度搜索。
1 #include<iostream> 2 #include<cstring> 3 #include<cmath> 4 using namespace std; 5 6 struct Node 7 { 8 int x,y; 9 }p[110]; 10 int vis[110]; 11 int flag=0; 12 int N,D; 13 14 int key(int); 15 int firststep(int); 16 int jump(int,int); 17 int DFS(int); 18 19 int main() 20 { 21 memset(vis,0,sizeof(vis)); 22 cin>>N>>D; 23 int i; 24 for(i=0;i<N;i++) 25 { 26 cin>>p[i].x>>p[i].y; 27 } 28 if(D>=42.5) 29 cout<<"Yes"<<endl; 30 else 31 { 32 for(i=0;i<N;i++) 33 { 34 if(!vis[i]&&firststep(i)) 35 DFS(i); 36 } 37 if(flag==1) 38 cout<<"Yes"<<endl; 39 else cout<<"No"<<endl; 40 } 41 return 0; 42 } 43 44 int key(int t)//判断是否可以成功到达彼岸 45 { 46 if(p[t].x-D<=50||p[t].x+D>=50||p[t].y-D<=-50||p[t].y+D>=50) 47 return 1; 48 else return 0; 49 } 50 int firststep(int t)//判断第一步是否能够成功跳跃 51 { 52 int p1=pow(p[t].x,2); 53 int p2=pow(p[t].y,2); 54 int r=(D+7.5)*(D+7.5); 55 if(p1+p2>=r) 56 return 1; 57 else return 0; 58 } 59 int jump(int j,int k)//判断能否从一个鳄鱼的头跳到另一个鳄鱼的头 60 { 61 int R1=pow(p[j].x-p[k].x,2); 62 int R2=pow(p[j].y-p[j].y,2); 63 int R=D*D; 64 if(R1+R2>=R) 65 return 1; 66 else return 0; 67 } 68 int DFS(int t) 69 { 70 vis[t]=1; 71 if(key(t)==1) 72 flag=1; 73 for(int i=0;i<N;i++) 74 { 75 if(!vis[i]&&jump(t,i)) 76 flag=DFS(i); 77 } 78 return flag; 79 }
刚开始怎么也找不到问题所在,检查了很多遍代码,最后发现原来是大于号和小于号的问题,所以以后考虑问题一定要想清楚。
但是第二次更改了大于和小于号后还是有错误,这是为什么呢?
进行多次修改并请教他人后发现,在主函数中,要先判断第一步是否成功跳跃,再将标记数组清零,否则会有坐标点不会被搜索到,而不会被搜索到的点很有可能可以跳跃。
1 #include<iostream> 2 #include<cstring> 3 #include<cmath> 4 using namespace std; 5 6 struct Node 7 { 8 int x,y; 9 }p[110]; 10 int vis[110]; 11 int flag=0; 12 int N,D; 13 14 int key(int); 15 int firststep(int); 16 int jump(int,int); 17 void DFS(int); 18 19 int main() 20 { 21 cin>>N>>D;int i; 22 for(i=0;i<N;i++) 23 cin>>p[i].x>>p[i].y; 24 25 if(D>=42.5) 26 cout<<"Yes"<<endl; 27 else 28 { 29 for(i=0;i<N;i++) 30 { 31 if(firststep(i)) 32 { 33 memset(vis,0,sizeof(vis)); 34 DFS(i); 35 } 36 } 37 if(flag==1) 38 cout<<"Yes"<<endl; 39 else cout<<"No"<<endl; 40 } 41 return 0; 42 } 43 44 int key(int t)//判断是否可以成功到达彼岸 45 { 46 if(D >= 50 - abs(p[t].x) || D >= 50 - abs(p[t].y)) 47 return 1; 48 49 return 0; 50 } 51 52 int firststep(int t)//判断第一步是否能够成功跳跃 53 { 54 if((D + 7.5)*(D + 7.5) >= p[t].x*p[t].x+p[t].y*p[t].y) 55 return 1; 56 57 return 0; 58 } 59 60 int jump(int j,int k)//判断能否从一个鳄鱼的头跳到另一个鳄鱼的头 61 { 62 int R1=pow(p[j].x-p[k].x,2); 63 int R2=pow(p[j].y-p[j].y,2); 64 int R=D*D; 65 if(R1+R2<=R) 66 return 1; 67 else return 0; 68 } 69 void DFS(int t) 70 { 71 vis[t]=1; 72 if(key(t)==1) 73 flag=1; 74 for(int i=0;i<N;i++) 75 { 76 if(!vis[i]&&jump(t,i)) 77 DFS(i); 78 } 79 return; 80 }
三、目标完成情况
上次的目标完成的还可以,在课后又重新巩固了二叉树会哈夫曼树的相关知识,加下来的目标是继续巩固图的遍历及应用的相关知识。