首页 > 代码库 > (三分)HDU5531 Rebuild

(三分)HDU5531 Rebuild

Archaeologists find ruins of Ancient ACM Civilization, and they want to rebuild it. 

The ruins form a closed path on an x-y plane, which has nn endpoints. The endpoints locate on (x1,y1)(x1,y1), (x2,y2)(x2,y2), ,(xn,yn)…,(xn,yn) respectively. Endpoint ii and endpoint i?1i?1are adjacent for 1<in1<i≤n, also endpoint 11 and endpoint nn are adjacent. Distances between any two adjacent endpoints are positive integers. 

To rebuild, they need to build one cylindrical pillar at each endpoint, the radius of the pillar of endpoint ii is riri. All the pillars perpendicular to the x-y plane, and the corresponding endpoint is on the centerline of it. We call two pillars are adjacent if and only if two corresponding endpoints are adjacent. For any two adjacent pillars, one must be tangent externally to another, otherwise it will violate the aesthetics of Ancient ACM Civilization. If two pillars are not adjacent, then there are no constraints, even if they overlap each other. 

Note that riri must not be less than 00 since we cannot build a pillar with negative radius and pillars with zero radius are acceptable since those kind of pillars still exist in their neighbors. 

You are given the coordinates of nn endpoints. Your task is to find r1,r2,,rnr1,r2,…,rnwhich makes sum of base area of all pillars as minimum as possible. 

技术分享


For example, if the endpoints are at (0,0)(0,0), (11,0)(11,0), (27,12)(27,12), (5,12)(5,12), we can choose (r1r1, r2r2, r3r3, r4r4)==(3.753.75, 7.257.25, 12.7512.75, 9.259.25). The sum of base area equals to 3.752π+3.752π+7.252π+12.752π+9.252π=988.8167.252π+12.752π+9.252π=988.816…. Note that we count the area of the overlapping parts multiple times. 

If there are several possible to produce the minimum sum of base area, you may output any of them.

InputThe first line contains an integer tt indicating the total number of test cases. The following lines describe a test case. 

The first line of each case contains one positive integer nn, the size of the closed path. Next nn lines, each line consists of two integers (xi,yi)(xi,yi) indicate the coordinate of the ii-th endpoint. 

1t1001≤t≤100 
3n1043≤n≤104 
|xi|,|yi|104|xi|,|yi|≤104 
Distances between any two adjacent endpoints are positive integers.
OutputIf such answer doesn‘t exist, then print on a single line "IMPOSSIBLE" (without the quotes). Otherwise, in the first line print the minimum sum of base area, and then print nn lines, the ii-th of them should contain a number riri, rounded to 2 digits after the decimal point. 

If there are several possible ways to produce the minimum sum of base area, you may output any of them.
Sample Input

3
4
0 0
11 0
27 12
5 12
5
0 0
7 0
7 3
3 6
0 6
5
0 0
1 0
6 12
3 16
0 12

Sample Output

988.82
3.75
7.25
12.75
9.25
157.08
6.00
1.00
2.00
3.00
0.00
IMPOSSIBLE

按点的数目奇偶分情况,奇数情况直接可以解方程,偶数情况其他所有数可以用r1表示,确定r1范围,三分即可。(这题精度有点神奇……)

  1 #include <iostream>
  2 #include <string>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <cstdio>
  6 #include <cmath>
  7 #include <queue>
  8 #include <set>
  9 #include <map>
 10 #include <list>
 11 #include <vector>
 12 #include <stack>
 13 #define mp make_pair
 14 //#define P make_pair
 15 #define MIN(a,b) (a>b?b:a)
 16 //#define MAX(a,b) (a>b?a:b)
 17 typedef long long ll;
 18 typedef unsigned long long ull;
 19 const int MAX=1e4+5;
 20 const int MAX_V=1e3+5;
 21 const ll INF=4e18+5;
 22 const double M=4e18;
 23 using namespace std;
 24 const int MOD=1e9+7;
 25 typedef pair<ll,int> pii;
 26 const double eps=1e-7;
 27 #define rank rankk
 28 int t,n;
 29 double x[MAX],y[MAX],d[MAX],r[MAX],g[MAX];
 30 int findb(double &l,double &r)
 31 {
 32     l=0,r=min(d[0],d[n-1]);
 33     for(int i=0;i<n-1;i++)
 34         if(i&1)
 35             l=max(l,g[i]);
 36         else
 37             r=min(r,g[i]);
 38 }
 39 void solve_odd()
 40 {
 41     double sum=0.0,an=0.0;
 42     for(int i=0;i<n;i++)
 43         if(i&1)
 44             sum-=d[i];
 45         else
 46             sum+=d[i];
 47     r[0]=sum/2.0;
 48     if(r[0]<-eps)
 49     {
 50         printf("IMPOSSIBLE\n");return;
 51     }
 52     else
 53     {
 54         for(int i=0;i<n;i++)
 55         {
 56             an+=r[i]*r[i];
 57             r[i+1]=d[i]-r[i];
 58             if(i+1!=n&&r[i+1]<-eps)
 59             {
 60                 printf("IMPOSSIBLE\n");return;
 61             }
 62         }
 63     }
 64     printf("%.2f\n",an*acos(-1.0));
 65     for(int i=0;i<n;i++)
 66         printf("%.2f\n",r[i]);
 67     return;
 68 }
 69 double get(double m) {
 70     double re=m*m,r=m;
 71     for (int i=0;i<n-1;i++) {
 72         r=d[i]-r;
 73         re+=r*r;
 74     }
 75     return re;
 76 }
 77 
 78 void solve_even()
 79 {
 80     if(abs(g[n-1])>eps)
 81     {
 82         printf("IMPOSSIBLE\n");return;
 83     }
 84     double l,r;
 85     findb(l,r);
 86     if(l>r+eps)
 87     {
 88         printf("IMPOSSIBLE\n");return;
 89     }
 90     while(r-l>eps)
 91     {
 92         double L,R;
 93         L=(2.0*l+r)/3.0;R=(l+2.0*r)/3.0;
 94         if(get(L)>=get(R)+eps)
 95             l=L;
 96         else
 97             r=R;
 98     }
 99     printf("%.2f\n",get(l)*acos(-1.0));
100     for(int i=0;i<n;i++)
101     {
102         printf("%.2f\n",l);
103         l=d[i]-l;
104     }
105 }
106 int main()
107 {
108     scanf("%d",&t);
109     while(t--)
110     {
111         scanf("%d",&n);
112         for(int i=0;i<n;i++)
113         {
114             scanf("%lf%lf",&x[i],&y[i]);
115             if(i)
116                 d[i-1]=sqrt((x[i]-x[i-1])*(x[i]-x[i-1])+(y[i]-y[i-1])*(y[i]-y[i-1]));
117         }
118         d[n-1]=sqrt((x[n-1]-x[0])*(x[n-1]-x[0])+(y[n-1]-y[0])*(y[n-1]-y[0]));
119         g[0]=d[0];
120         for(int i=1;i<n;i++)
121             if(i&1)
122                 g[i]=g[i-1]-d[i];
123             else
124                 g[i]=g[i-1]+d[i];
125         if(n&1)
126             solve_odd();
127         else
128             solve_even();
129     }
130     return 0;
131 }

 

(三分)HDU5531 Rebuild