uva 11853 paintball(好题)——yhx

uva 11853 paintball(好题)——yhx_第1张图片

 1 #include
 2 #include
 3 #include
 4 struct circ
 5 {
 6     double x,y,r;
 7 }a[1010];
 8 bool vis[1010];
 9 int n;
10 double ans_l,ans_r;
11 double min(double a,double b)
12 {
13     return aa:b;
14 }
15 bool conn(int x,int y)
16 {
17     double dis=sqrt((a[x].x-a[y].x)*(a[x].x-a[y].x)+(a[x].y-a[y].y)*(a[x].y-a[y].y));
18     if (dis<=a[x].r+a[y].r) return 1;
19     return 0;
20 }
21 bool dfs(int x)
22 {
23     int i; 
24     vis[x]=1;
25     if (a[x].y-a[x].r<=0) return 1;
26     if (a[x].x-a[x].r<=0)
27       ans_l=min(ans_l,a[x].y-sqrt(a[x].r*a[x].r-a[x].x*a[x].x));
28     if (a[x].x+a[x].r>=1000)
29       ans_r=min(ans_r,a[x].y-sqrt(a[x].r*a[x].r-(1000-a[x].x)*(1000-a[x].x)));
30     for (i=1;i<=n;i++)
31       if (vis[i]==0&&conn(x,i))
32         if (dfs(i)) return 1;
33     return 0;
34 }
35 int main()
36 {
37     int i,j,k,m,p,q,x,y,z;
38     bool b;
39     while (scanf("%d",&n)==1)
40     {
41         ans_l=ans_r=1000;
42         memset(a,0,sizeof(a));
43         memset(vis,0,sizeof(vis));
44         for (i=1;i<=n;i++)
45           scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].r);
46         b=0;
47         for (i=1;i<=n;i++)
48           if (vis[i]==0&&a[i].y+a[i].r>=1000&&dfs(i))
49           {
50               printf("IMPOSSIBLE\n");
51               b=1;
52               break;
53           }
54         if (b==0) printf("0.00 %.2lf 1000.00 %.2lf\n",ans_l,ans_r);
55     }
56 }

题意需要几步转化。

关键要自己手画几个图感受一下。

避免攻击离开战场

→1.以敌人为障碍物,找到一条从左到右的通路。

→2.以敌人为路,找到一条从上到下的通路。(如果有一条上下贯通的路,则一定把地图分为左右两部分,即不存在左右通路。)

从每个与上边界相交或相切的圆开始搜索和它相交或相切的圆。如果搜到一个和下边界相交或相切的圆,则判定impossible。

于是判定就解决了。

求解可以与判定同时进行,每搜索到一个圆,就看他是否与左右边相交或相切,如果是的话那交点以上的部分就被困在角上(因为如果搜索到了这个圆,那他一定直接或间接连到了上边界),需要用它的靠下的交点更新答案。

你可能感兴趣的:(uva 11853 paintball(好题)——yhx)