这个题是2017noip提高组的真题,是一个深度搜索题,得分轨迹:10-80-100pts。
在三维空间里,存在可能连通的洞(半径r),问是否可以通过这些洞从底部到达顶部。一开始我联想到了01迷宫,以联通块的方式求解,但发现不可。于是就单纯想用一个一维的dfs去枚举,发现这个dfs的时间复杂度很低,似乎每一个节点访问一遍即可。首先确定了每次要枚举的是当前的坐标,如果z+r>=h则flag=true,如果没有就for(1~n),打上标记,但在这里,每一个点只需要走一次就可以了,因为从2-4如果到不了,那么从3-4也到不了,所以不用回溯。但是需要有一个入口,那么要把dfs放到一个for里,如果z<=r,那么进去。但是对于数据类型的定义我出现了问题,请教了lz,hhs,lxy大佬。
1.要想骗到分或者代码写崩了,仔细看数据范围,比如这个题n=1,直接判断能不能到达底部和顶部就20分了。
2.多组数据输出时别忘了换行。
3.计算公式的正确性一定要保证,调试的时候心态放平,按部就班,应该可以找出来的。
4.对于数据的类型定义,sqrt要double,平方要long long这些都要想清楚
代码
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 using namespace std; 8 struct node{ 9 double x;10 double y;11 double z;12 }a[1000005];13 int book[1000005];14 int T;15 int n,h;16 long long r; 17 bool flag=false;18 long long d;19 long long dis(double x,double y,double z,double xx,double yy,double zz){20 return ((x-xx)*(x-xx)+(y-yy)*(y-yy)+(z-zz)*(z-zz));21 // return ((x-xx)^2+(y-yy)^2+(z-zz)^2);22 }23 void dfs(double x,double y,double z){24 if(z+r>=h){25 flag=true;26 return;27 }28 if(flag==false){29 for(int i=1;i<=n;i++){30 if(book[i]==0){ 31 //cout< >n>>h>>r;47 for(int i=1;i<=n;i++){48 cin>>a[i].x>>a[i].y>>a[i].z;49 book[i]=0;50 }51 for(int i=1;i<=n;i++){52 if(flag==true) break;53 if(a[i].z<=r){54 // cout< <