当我这样一个蒟蒻看到题解区里都是类似并查集、dfs、bfs 这种高深的东西时,真的很难受(因为看不懂)
于是我整了一个小时,终于整出一个人畜无害老少皆宜即使是蒟蒻也能看懂的代码了
以上是废话
思路
简单来说,先按高矮(即 z)从小到大排序,如果一个洞能和它前面任何一个洞相连或是直接与下表面相连,就存进一个数组,如果数组中有哪个能和上表面相连,就输出 Yes,反之,输出 No。
因为事先已经排过了序,所以可以保证数组中的数都是与下表面相连的,就像 a1 与下底面相连,a2 与 a1 相连,所以 a2 也是和下底面相连的,所以不用管它和哪个相连,知道是连着的就对了
附上喜闻乐见的 AC 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define ll long long using namespace std; struct qwq { ll x; ll y; ll z; }; bool cmp(qwq a,qwq b) { if(a.z!=b.z) return a.z<b.z; if(a.x!=b.x) return a.x<b.x; if(a.y!=b.y) return a.y<b.y; } ll dist(ll x1,ll y1,ll z1,ll x2,ll y2,ll z2) { return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2); } ll t,n,h,r,s,flag; qwq tree[1010],g[1010]; int main() { scanf("%lld",&t); for(int c=1;c<=t;c++) { scanf("%lld%lld%lld",&n,&h,&r); s=0; flag=0; memset(tree,0,sizeof(tree)); for(int i=1;i<=n;i++) scanf("%lld%lld%lld",&g[i].x,&g[i].y,&g[i].z); sort(g+1,g+1+n,cmp); for(int i=1;i<=n;i++) { flag=0; if(g[i].z-r<=0) { s++; tree[s].x=g[i].x; tree[s].y=g[i].y; tree[s].z=g[i].z; } for(int j=1;j<=s;j++) if(dist(g[i].x,g[i].y,g[i].z,tree[j].x,tree[j].y,tree[j].z)<=4*r*r) { s++; tree[s].x=g[i].x; tree[s].y=g[i].y; tree[s].z=g[i].z; break; } if(tree[s].z+r>=h) { flag=1; break; } } if(flag) printf("Yes\n"); else printf("No\n"); } return 0; }
|
如果哪里做的不对,请各位大佬帮忙指出,十分感谢