1. 程式人生 > >NOIP 2017 Day2 T1 奶酪

NOIP 2017 Day2 T1 奶酪

c++ names str day ica while -- 是否 ++

luogu題面

兩天中唯一的良心題,然而我在考場上蜜汁 RE 成70...

做法應該很多,樸素做法應該有 並查集搜索

我打的 並查集,不過好像 DFS 快的一批;

思路很簡單,就是把能連在一起的洞並成同一個集

最後要查詢一下底面和頂面是否同一集合中;

就完了(好裸啊然而我就是沒AC

復雜度 O(n2×T)

AC代碼如下,個人感覺還比較清晰(244 ms 2183 kb):

技術分享圖片
#include<bits/stdc++.h>
#define m(a,b) memset(a,b,sizeof(a))
#define ll long long
using namespace
std; int f[1002]; struct _{ int x,y,z; }a[1002]; inline bool cmp(_ a,_ b){ return a.z<b.z; } inline ll q(ll x){ return x*x; } inline double dis(_ a,_ b){ return (double)sqrt(q(a.x-b.x)+q(a.y-b.y)+q(a.z-b.z)); } int find(int x){ if(f[x]==x) return x; return f[x]=find(f[x]); }
void bing(int a,int b){ int x=find(a),y=find(b); f[x]=y; } inline void init(){ m(a,0),m(f,0); } int main(){ int n,t,h,r; scanf("%d",&t); while(t--){ init(); scanf("%d%d%d",&n,&h,&r); for(int i=1;i<=n+1;i++) f[i]=i; for(int i=1;i<=n;i++) scanf(
"%d%d%d",&a[i].x,&a[i].y,&a[i].z); sort(a+1,a+n+1,cmp); for(int i=1;i<n;i++) for(int j=i+1;j<=n&&a[j].z-(r<<1)<=a[i].z;j++) if(dis(a[i],a[j])<=r<<1) bing(i,j); for(int i=1;i<=n;i++) if(a[i].z<=r) bing(0,i); for(int i=n;i>0;i--) if(a[i].z>=h-r) bing(i,n+1); if(find(0)==find(n+1)) printf("Yes\n"); else printf("No\n"); } return 0; }
View Code

%%% 寫 掃描線 的 Dalao %%%

By The_Seventh——一個剛學了半年的高一蒟蒻

2017-12-23 18:08:34

NOIP 2017 Day2 T1 奶酪