[题解]NOIP2017D2TI奶酪

    

  1 #include<bits/stdc++.h>   //万能头
  2 using namespace std;
  3 typedef long long ll;
  4 const int MAXA = 1010;
  5 ll n, h, r;
  6 ll x[MAXA], y[MAXA], z[MAXA];
  7 int fa[MAXA];
  8 bool bookup[MAXA], bookdown[MAXA]; //这两个数组存是否与上下表面相通
  9 inline void init()
 10 {
 11     for(register int i = 0; i < MAXA; i++)  fa[i] = i;
 12     memset(x, 0, sizeof(x));
 13     memset(y, 0, sizeof(y));
 14     memset(z, 0, sizeof(z));
 15     memset(bookup, 0, sizeof(bookup));
 16     memset(bookdown, 0, sizeof(bookdown)); //各种初始化,这边很重要
 17 }
 18 inline void openFile()
 19 {
 20     freopen("cheese.in", "r", stdin);
 21     freopen("cheese.out", "w", stdout);
 22 }
 23 inline void closeFile()
 24 {
 25     fclose(stdin);
 26     fclose(stdout);
 27 }
 28 inline int read()    //快读
 29 {
 30     char ch = getchar();
 31     int temp = 0, fh = 1;
 32     while(ch > '9' || ch < '0')if(ch == '-')fh = -1, ch = getchar();
 33     while(ch <= '9' && ch >= '0')temp = temp * 10 + ch - '0', ch = getchar();
 34     return temp * fh;
 35 }
 36 inline double get_dist(ll x1, ll y1, ll z1, ll x2, ll y2, ll z2)
 37 {
 38     ll dx = (x1 - x2) * (x1 - x2);
 39     ll dy = (y1 - y2) * (y1 - y2);
 40     ll dz = (z1 - z2) * (z1 - z2);
 41     double temp = sqrt(dx + dy + dz);
 42     return temp;
 43     //这里请用long long,不然会爆int!!!
 44     //话说我旁边那个人就是因为没写long long 100变80.(这个人就差20分一等)
 45     //利用公式算距离——其实就是神奇的勾股定理啦
 46 }
 47 int getf(int n)
 48 {
 49     if(fa[n] == n)    return n;
 50     else fa[n] = getf(fa[n]); //路径压缩
 51     return fa[n];
 52     //并查集找祖先 顺带路径压缩
 53 }
 54 inline void toge(int x, int y)    //并查集合并
 55 {
 56     int fx = getf(x), fy = getf(y);
 57     if(fx != fy)    fa[fy] = fx;
 58     if(bookup[fx] || bookup[fy])    bookup[fy] = bookup[fx] = true;
 59     if(bookdown[fx] || bookdown[fy])bookdown[fy] = bookdown[fx] = true;
 60     //这边两个判断 判断是否和上下表面相同 把结果保存都赋给祖先,直接找祖先就好了
 61 }
 62 int main()
 63 {
 64     //  openFile();    //文件重定向
 65     int t = read();
 66     for(register int i = 1; i <= t; i++) //我知道很多人喜欢写while(t--)但我还是喜欢for没有理由
 67     {
 68         init();    //每次都要初始化,不然会出锅
 69         n = read();
 70         h = read();
 71         r = read();
 72         for(register int j = 1; j <= n; j++)
 73         {
 74             x[j] = read();
 75             y[j] = read();
 76             z[j] = read();
 77             if(z[j] + r >= h)    bookup[getf(j)] = 1;
 78             if(z[j] - r <= 0)    bookdown[getf(j)] = 1; //判断是否与上下表面相同
 79             for(register int k = 1; k < j; k++)
 80             {
 81                 if(getf(k) == getf(j))    continue; //如果已经联通了,再判断是否联通无关紧要
 82                 double temp = get_dist(x[j], y[j], z[j], x[k], y[k], z[k]);
 83                 if(temp <= 2 * r)    toge(j, k); //每读入一个数就判断是否与之前的联通
 84                 //这里判断是否联通的比较暴力,复杂度O(n^2)
 85             }
 86         }
 87         bool flag = 0;
 88         for(register int i = 1; i <= n; i++)
 89         {
 90             int faa = getf(i); //这里判断是否有一个联通快能够联通上下表面
 91             if(bookup[faa] && bookdown[faa])
 92             {
 93                 flag = 1;
 94                 break;
 95             }
 96         }
 97         if(flag)    printf("Yes\n");
 98         else        printf("No\n");    //输出结果不用多说吧……
 99     }
100     //  closeFile();    //取消文件重定向
101     return 0;
102 }

 

posted @ 2019-07-19 14:12  ◆寻梦∽天涯◆  阅读(180)  评论(0编辑  收藏  举报