E - Rebuild UVALive - 7187 (二次函数极值问题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5531

Problem Description

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 n endpoints. The endpoints locate on (x1,y1), (x2,y2), …,(xn,yn) respectively. Endpoint i and endpoint i−1 are adjacent for 1<i≤n, also endpoint 1 and endpoint n 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 i is ri. 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 ri must not be less than 0 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 n endpoints. Your task is to find r1,r2,…,rn which makes sum of base area of all pillars as minimum as possible.

For example, if the endpoints are at (0,0), (11,0), (27,12), (5,12), we can choose (r1, r2, r3, r4)=(3.75, 7.25, 12.75, 9.25). The sum of base area equals to 3.752π+7.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.

Input

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

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

1≤t≤100
3≤n≤104
|xi|,|yi|≤104
Distances between any two adjacent endpoints are positive integers.

Output

If 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 n lines, the i-th of them should contain a number ri, 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

Source

2015ACM/ICPC亚洲区长春站-重现赛(感谢东北师大)

Recommend

hujie

题解:对于题目分析可得一些性质:

1:一个圆的半径确定,其他的圆的半径也随之确定.

2:对于n,分奇偶讨论,奇数情况下化简可得:若有解必有唯一解,否则无解.偶数情况下构造二次函数有一变元,从而转换为二次函数的极值问题.

3:限制:半径必须都>=0

#include <bits/stdc++.h>
#define met(a, b) memset(a, b, sizeof(a))
#define ll long long
#define ull unsigned long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef pair<int,int>P;
const int maxn=100010;
const double eps=1e-10;
const double pi=acos(-1);
P p[maxn];
double d[maxn],f[maxn];
double dist(P a,P b)
{
  return sqrt((a.first-b.first)*(a.first-b.first)+(a.second-b.second)*(a.second-b.second));
}
int main()
{
  int T;
  cin>>T;
  while(T--){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)cin>>p[i].first>>p[i].second;
    for(int i=1;i<=n;i++){
      if(i==n)d[i]=dist(p[i],p[1]);
      else d[i]=dist(p[i],p[i+1]);
    }
    double maxx=0x3f3f3f3f,minn=0;//极值上下限
    f[1]=0;
    for(int i = 2; i <=n ; i++)
    {
      f[i] = d[i-1] - f[i-1];
      if(i%2==0 && f[i] < maxx)//若为偶数点,则该圆的半径只能减小这么多(即第一个圆的半径只能增大这么多),更新最大值下限
      {
        maxx = f[i];
      }
      if(i%2==1 && (-f[i]) > minn)//若为奇数点,且此时f[i]小与0,则必须第一个圆的半径更新为该值,更新最小值上限
      {
        minn = -f[i];
      }
    }
    if(minn >= maxx + eps )//无解
    {
      printf("IMPOSSIBLE\n");
      continue;
    }
    if(n%2==1){//奇数个点,有解则必有唯一解,否则无解
      double x=0;//第一个圆的半径x=(d1-d2+d3-d4...)/2,唯一解.
      for(int i=1;i<=n;i++){
        if(i%2==1)x+=d[i];
        else x-=d[i];
      }
      x/=2;
      if(x<=minn-eps||x>=maxx+eps){
        cout<<"IMPOSSIBLE"<<endl;
        continue;
      }
      double area=0;
      for(int i=1;i<=n;i++){
        if(i%2==1)area+=(f[i]+x)*(f[i]+x);
        else area+=(f[i]-x)*(f[i]-x);
      }
      area*=pi;
      printf("%.2f\n",area);
      for(int i=1;i<=n;i++){
        if(i%2==1)printf("%.2f\n",f[i]+x);
        else printf("%.2f\n",f[i]-x);
      }
    }
    else{//偶数情况构造二次函数,y=a*x*x+b*x+c
      double now=0;
      for(int i=1;i<=n;i++){
        if(i%2==1)now+=d[i];
        else now-=d[i];
      }
      if(fabs(now)>eps||minn-maxx>eps){
        cout<<"IMPOSSIBLE"<<endl;
        continue;
      }
      double a=n;
      double b=0,c=0;
      for(int i=1;i<=n;i++){
        if(i%2==1){
          b+=2*f[i];
        }
        else{
          b-=2*f[i];
        }
        c+=f[i]*f[i];
      }
      double x=-b/(2*a);
      if(x<minn+eps)x=minn;
      if(x>maxx-eps)x=maxx;
      double area=a*x*x+b*x+c;
      area*=pi;
      printf("%.2f\n",area);
      for(int i=1;i<=n;i++){
        if(i%2==1)printf("%.2f\n",f[i]+x);
        else printf("%.2f\n",f[i]-x);
      }
    }
  }
  return 0;
}

原文地址:https://www.cnblogs.com/cherish-lin/p/11503242.html

时间: 2024-09-30 00:03:39

E - Rebuild UVALive - 7187 (二次函数极值问题)的相关文章

(转载)SVM-基础(五)

作为支持向量机系列的基本篇的最后一篇文章,我在这里打算简单地介绍一下用于优化 dual 问题的 Sequential Minimal Optimization (SMO) 方法.确确实实只是简单介绍一下,原因主要有两个:第一这类优化算法,特别是牵涉到实现细节的时候,干巴巴地讲算法不太好玩,有时候讲出来每个人实现得结果还不一样,提一下方法,再结合实际的实现代码的话,应该会更加明了,而且也能看出理论和实践之间的差别:另外(其实这个是主要原因)我自己对这一块也确实不太懂.  先回忆一下我们之前得出的要

机器学习知识点总结(2)

二.基本概念 1 有监督学习与无监督学习 根据样本数据是否带有标签值,可以将机器学习算法分成有监督学习和无监督学习两类.有监督学习的样本数据带有标签值,它从训练样本中学习得到一个模型,然后用这个模型对新的样本进行预测推断.有监督学习的典型代表是分类问题和回归问题. 无监督学习对没有标签的样本进行分析,发现样本集的结构或者分布规律.无监督学习的典型代表是聚类,表示学习,和数据降维,它们处理的样本都不带有标签值. 2 有分类问题与回归问题 在有监督学习中,如果样本的标签是整数,则预测函数是一个向量到

2015ACM/ICPC亚洲区长春站 E hdu 5531 Rebuild

Rebuild Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 446    Accepted Submission(s): 113 Problem Description Archaeologists find ruins of Ancient ACM Civilization, and they want to rebuild i

Kooboo 加Search功能 必须先ReBuild Index Data

加Search功能 有几个要点 1. 需要在Kooboo 必须先 ReBuild Index Data 2. 需要在要搜索的page中启用搜索索引 搜索的代码 @using Kooboo.CMS.Content.Models @using Kooboo.CMS.Search @{ var result = Repository.Current.Search("Dolor", 1, 10); } @result.TotalItemCount @foreach (var item in r

UVALive 4848 Tour Belt

F - Tour Belt Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVALive 4848 Description Korea has many tourist attractions. One of them is an archipelago (Dadohae in Korean), a cluster of small islands sca

UVALive 6467 Strahler Order 拓扑排序

这题是今天下午BNU SUMMER TRAINING的C题 是队友给的解题思路,用拓扑排序然后就可以了 最后是3A 其中两次RE竟然是因为: scanf("%d",mm); ORZ 以后能用CIN还是CIN吧 QAQ 贴代码了: 1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <math.h> 5 #include <iostre

极值问题

题目: 已知m.n为整数,且满足下列两个条件: ① m.n∈1,2,...,K,(1≤K≤10^9) ② (n^ 2-mn-m^2)^2=1 编一程序,对给定K,求一组满足上述两个条件的m.n,并且使m^2+n^2的值最大.例如,若K=1995,则m=987,n=1597,则m.n满足条件,且可使m^2+n^2的值最大. 输入 输入仅一行,K的值. 输出 输出仅一行,m^2+n^2的值. 样例输入 1995 样例输出 3524578 题目字数不多,但是条件2看起来貌似有点复杂,但实际上,它也是个

四维偏序(K-D-Tree+rebuild)

其实只是放个代码,会K-D-Tree的同学看了就知道怎么rebuild了,其实也是很简单粗暴的-- 单独再发一次吧,感觉把代码跟之前的一起发不知道啥时候就找不到了-- 1 #include<bits/stdc++.h> 2 #define N 50010 3 #define inf 1000000009 4 #define lson (t1[o].l) 5 #define rson (t1[o].r) 6 using namespace std; 7 typedef long long ll;

UVALive 7077 Little Zu Chongzhi&#39;s Triangles (有序序列和三角形的关系)

这个题……我上来就给读错了,我以为最后是一个三角形,一条边可以由多个小棒组成,所以想到了状态压缩各种各样的东西,最后成功了……结果发现样例过不了,三条黑线就在我的脑袋上挂着,改正了以后我发现N非常小,想到了回溯每个棍的分组,最多分5组,结果发现超时了……最大是5^12 =  244,140,625,厉害呢…… 后来想贪心,首先想暴力出所有可能的组合,结果发现替换问题是一个难题……最后T T ,我就断片了.. 等看了别人的办法以后,我才发现我忽视了三角形的特性,和把数据排序以后的特点. 如果数据从