https://vjudge.net/problem/UVA-11853
题目
一堆人玩水弹(也许是吧),知道他们的坐标和攻击范围,问你从西边到东边能否不被水弹砸。找出西边进入的位置和东边出去的位置。
$nleqslant1000$
题解
最近一直在写水题……为了看看每道题使用的时间,还写了个计时器,但是这题用的时间太长了……
WA了一次,计算上罚时就是2小时了= =
坐标没看清楚,样例都纠结了半小时,然后少考虑了一种情况
按照紫书上的题解:
看有没有一条把这块地分成左右两边的路……
如果有就无解,没有就有解
然后从北边开始便利,找到与左右边界相交的最南边的坐标
AC代码
#include<bits/stdc++.h> using namespace std; #define REP(i,x,y) for(register int i=(x); i<(y); i++) #define REPE(i,x,y) for(register int i=(x); i<=(y); i++) #ifdef sahdsg #define DBG(a,...) printf(a, ##__VA_ARGS__) #else #define DBG(a,...) (void)0 #endif #define MAXN 1007 int n; struct yuan { double r,x,y; } arr[MAXN]; inline bool conn(int i, int j) { double rr = arr[i].r+arr[j].r; double dx = arr[i].x-arr[j].x; double dy = arr[i].y-arr[j].y; rr*=rr; dx*=dx; dy*=dy; return dx+dy<=rr; } bool vis[MAXN]; inline bool bfs1(int i) { queue<int> q; q.push(i); vis[i]=true; while(!q.empty()) { int now = q.front(); q.pop(); if(arr[now].y-arr[now].r<=0) return true; REP(i,0,n) { if(!vis[i] && conn(now,i)) { q.push(i); vis[i]=true; } } } return false; } double ans1, ans2; bool has1, has2; inline void bfs2(int i) { queue<int> q; q.push(i); while(!q.empty()) { int now = q.front(); q.pop(); if(arr[now].x-arr[now].r<=0) { ans1=min(ans1,arr[now].y-sqrt(arr[now].r*arr[now].r-arr[now].x*arr[now].x)); } if(arr[now].x+arr[now].r>=1000) { double dx=1000.0-arr[now].x; ans2=min(ans2,arr[now].y-sqrt(arr[now].r*arr[now].r-dx*dx)); } REP(i,0,n) { if(!vis[i] && conn(now,i)) { q.push(i); vis[i]=true; } } } } int main() { #ifdef sahdsg freopen("in.txt","r",stdin); #endif while(~scanf("%d", &n)) { REP(i,0,n) { double &x=arr[i].x, &y=arr[i].y, &r=arr[i].r; scanf("%lf%lf%lf", &x, &y, &r); } bool f=true; memset(vis,0,sizeof vis); REP(i,0,n) { double &x=arr[i].x, &y=arr[i].y, &r=arr[i].r; if(!vis[i] && y+r>=1000) { if(bfs1(i)) { f=false; break; } } } if(!f) { puts("IMPOSSIBLE"); } else { memset(vis,0,sizeof vis); ans1=ans2=1000; has1=has2=false; REP(i,0,n) { double &x=arr[i].x, &y=arr[i].y, &r=arr[i].r; if(!vis[i] && y+r>=1000) { bfs2(i); } } printf("0.00 %.2lf 1000.00 %.2lf ", ans1, ans2); } } return 0; }