uva 11853 paintball(好题)——yhx

来源:互联网 发布:网络整改方案 编辑:程序博客网 时间:2024/04/30 15:04

 1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 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 a<b?a: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。

于是判定就解决了。

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

0 0
原创粉丝点击