• (三分)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 i1i−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
    ");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
    ");return;
     61             }
     62         }
     63     }
     64     printf("%.2f
    ",an*acos(-1.0));
     65     for(int i=0;i<n;i++)
     66         printf("%.2f
    ",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
    ");return;
     83     }
     84     double l,r;
     85     findb(l,r);
     86     if(l>r+eps)
     87     {
     88         printf("IMPOSSIBLE
    ");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
    ",get(l)*acos(-1.0));
    100     for(int i=0;i<n;i++)
    101     {
    102         printf("%.2f
    ",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 }
  • 相关阅读:
    作妖系列——更改spyder黑色主题
    latex beamer 插入代码
    LaTeX 如何在文档的侧面插入图片实现"绕排"?
    svm
    约束优化方法之拉格朗日乘子法与KKT条件
    Latex algorithm
    对于连续目标函数的学习问题,当误差为正态分布,而且在没有任何先验知识的条件下,最大似然估计与最小均方误差等价
    R语言table()函数
    高性能Linux服务器配置
    深度学习
  • 原文地址:https://www.cnblogs.com/quintessence/p/6940822.html
Copyright © 2020-2023  润新知