Lo Valley P3958 Cheese

I would like to use this topic to commemorate my explosive NOIp2017


Although many people say that this question is a combined search, the search is also stress-free. The details of the search in the examination room were written down, and it broke a score of 80. I didn't want to see this question today, finally AC

  • First of all, this question needs to consider the problem of accuracy. Although the person who asked the question does not have the accuracy of the tumor card, it is still worth noting. The solution is also very simple, remove the square root operation, but square the radius, that is, \(2r\) ---> \(4r^2\) , this is OK. But remember to use \(\rm long\;long\) , otherwise it will explode \(\rm int\)

  • Then consider how to search, I save each set of data into a map with a forward star, and then search for this map. This question has a very special feature, that is, it does not need to backtrack, because if a point can't reach the end point, it will still not reach the end point if it is searched again, so why should we search it again? Just throw it away span

code above

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
inline int read() //快读 
{
    int k=0,f=1;
    char c=getchar();
    for(;!isdigit(c);c=getchar())
    if(c=='-')f=-1;
    for(;isdigit(c);c=getchar())
    k=k*10+c-48;
    return k*f;
}
struct zzz{  //存空洞的坐标 
    ll x,
       y,
       z;
}che[1001];
inline ll f(zzz x,zzz y)  //计算空洞距离 
{
    return (x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y)+(x.z-y.z)*(x.z-y.z);
}
struct hhh{  //存图 
    int f,
        t,
        nex;
}e[2000001];  int head[1001]; int tot;
inline void add(int x,int y)  //前向星 
{
    e[++tot].f=x;
    e[tot].t=y;
    e[tot].nex=head[x];
    head[x]=tot;
}
int s[1001],flag; bool en[1001],vis[1001]; 
//s:可以当作起点的空洞  flag:可以当作起点的空洞的个数  en:终点空洞  vis:这个点是否走过 
bool ans;  //判断能否到达上表面 
void dfs(int str)  //搜索主体 
{
    if(en[str])  //找到终点就不用搜了 
    {
        ans=1;  return ;
    }
    for(int i=head[str];i;i=e[i].nex)  //向下寻找能搜的点 
      if(!vis[e[i].t])
      {
          vis[e[i].t]=1;  //直接标志为搜过,不再回溯 
          dfs(e[i].t);  //向下搜索 
          if(ans)
            return ;
      }
}
int main()
{
    int t; t=read();
    int n; ll h,r;
    while(t--)
    {
        tot=0; memset(head,0,sizeof(head)); ans=0;
        flag=0; memset(en,0,sizeof(en)); memset(vis,0,sizeof(vis)); //清空所有变量 
        n=read(),h=read(),r=read();
        for(int i=1;i<=n;i++)  //输入数据 + 处理成图 
        {
            che[i].x=read(),che[i].y=read(),che[i].z=read();
            
            if(che[i].z<=r) //如果z>=半径,那么这个空洞和下表面接触,将它加入起点 
              s[++flag]=i;
            if(che[i].z>=h-r) //同理,如果z>=h-r,那它和上表面接触,将它加入终点 
              en[i]=1;
            for(int j=1;j<i;j++)
              if(f(che[i],che[j])<=4*r*r) //防止精度损失 
              {
                  add(i,j);  add(j,i);
              }
        }
        // 搜索 + 输出 
        bool jjj=0;
        for(int i=1;i<=flag;i++)
        {
            dfs(s[i]);
            if(ans)
            {
                printf("Yes\n");
                jjj=1;
                break;
            }
        }
        if(!jjj)
          printf("No\n");
    }
    return 0;
}
  • Advertise it

 The Los Valley Blog and Blog Garden Blog under

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324574066&siteId=291194637