zoukankan      html  css  js  c++  java
  • P3958奶酪

    这个题是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 #include<iostream>
     2 #include<cstdio>
     3 #include<string>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<algorithm>
     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<<dis(x,y,z,a[i].x,a[i].y,a[i].z);
    32                 if(dis(x,y,z,a[i].x,a[i].y,a[i].z)<=r*r*4){//相交或相切 
    33                     book[i]=1;
    34                      dfs(a[i].x,a[i].y,a[i].z);
    35                      //cout<<i<<endl;
    36                 }
    37             }
    38             else continue;
    39         }        
    40     }    
    41 } 
    42 int main(){
    43     scanf("%d",&T);
    44     for(int i=1;i<=T;i++){
    45         flag=false;
    46         cin>>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<<i<<endl;
    55                 book[i]=1;
    56                 dfs(a[i].x,a[i].y,a[i].z);
    57             }
    58         }
    59         if(flag==true) cout<<"Yes"<<endl;
    60         else cout<<"No"<<endl; 
    61     }    
    62     return 0;
    63 } 
  • 相关阅读:
    C#遍历List并删除某个或者几个元素的方法
    7月清北学堂培训 Day 4
    7月清北学堂培训 Day 3
    7月清北学堂培训 Day 2
    7月清北学堂培训 Day 1
    P1383 高级打字机
    P2401 不等数列
    P1412 经营与开发
    P1314 聪明的质监员
    2019.7.9 校内测试 T3 15数码问题
  • 原文地址:https://www.cnblogs.com/china-mjr/p/11333255.html
Copyright © 2011-2022 走看看