【POJ1819】Disks——几何工具

Disks

Time Limit: 1000MS Memory Limit: 30000K

Description

Consider N floating point numbers N representing the radii of N disks. We fix a disk in the xOy system, if we position it at a positive coordinate x (big enough), tangential to the 0x axis and above it and after that we push it to 0y until it becomes tangent to 0y or to the first disk that it meets on the way. In the configuration that results by fixing in order all the given disks, some of them can be considered as being dispensible, because, if we eliminate them, the total width of the configuration is the same, which means that there is no disk that can be moved to the left.

Identify all the indispensible disks for a given configuration (in the configuration from above; the gray disks are dispensible).

Input

The input has the following structure:

  • the first line contains N ( N <= 1000), the number of disks;
  • the next N lines contain N real numbers representing the radii of the disks, in the order they are fixed in the configuration.

Output

The output will have the following structure:

  • the first line will contain an integer K, representing the number of dispensable disks;
  • each of the next K lines will contain the order number of the dispensable disks.

Sample Input

7
4
0.1
0.5
3
0.5
4
1
Sample Output
3
2
3
5
Source
Romania OI 2002

给你从左向右的一堆圆,判断哪些圆不需要

#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>

using namespace std;

const double eps = 1e-6;
const double Pi = acos(-1.0);
const int INF = 0x3f3f3f3f;

typedef struct Point
{
    double x,y;

    Point(){}

    Point(double _x,double _y):x(_x),y(_y){}

    Point operator + (const Point &a) const
    {
        return Point(x+a.x,y+a.y);
    }

    Point operator - (const Point &a) const
    {
        return Point(x-a.x,y-a.y);
    }

    double operator * (const Point &a) const
    {
        return x*a.x+y*a.y;
    }

    Point operator * (const double &a) const
    {
        return Point(a*x,a*y);
    }

    double operator ^ (const Point &a) const
    {
        return x*a.y-y*a.x;
    }
    Point operator / (const double &a) const
    {
        return Point(x/a,y/a);
    }
}Vector;

typedef struct node
{
    double r;

    Point CC;

    node(){}

    node(Point _C,double _r):CC(_C),r(_r){}
}Circ;


int dbcmp(double x)
{
    return fabs(x)<eps?0:(x>0?1:-1);
}

Point GetPointCircToCirc(Circ C,double r)//求出另一圆的圆心
{
    double a1 = C.r/r;

    double a2 = C.r-r;

    double a3 = a2/(a1+1)*a1;

    double a4 = sqrt(C.r*C.r-a3*a3);

    return Point(C.CC.x+a4+a4/a1,r);
}

bool cmp(Point a,Point b)
{
    return dbcmp(a.x-b.x)>0;
}

Circ C[1100];

bool vis[1100];

int main()
{
    int n;

    while(~scanf("%d",&n))
    {
        memset(vis,false,sizeof(vis));

        for(int i = 0;i<n;i++) 
        {
            scanf("%lf",&C[i].r);

            C[i].CC.x = C[i].r;

            C[i].CC.y = C[i].r;
        }

        double  Max = 0;

        int Ans;

        for(int i = 1;i<n;i++)
        {
            Point ant;

            int flag = -1;

            for(int j = 0;j<i;j++)
            {
                if(vis[j]) continue;

                ant = GetPointCircToCirc(C[j],C[i].r);

                if(cmp(ant,C[i].CC)) 
                {
                    C[i].CC = ant;
                    flag = j;
                }
            }
            if(dbcmp(C[i].CC.x+C[i].r-Max) > 0)
            {
                Max = C[i].CC.x+C[i].r;

                Ans = i;
            }

            for(int j = flag + 1;j<i;j++) vis[j] = true;

        }
        for(int i = Ans+1; i <n;i++)
        {
            if(vis[i]) continue;

            if(dbcmp(Max-C[i].CC.x-C[i].r)>=0)
            {
                vis[i] = true;
            }
        }

        int ans = 0;

        for(int i = 0 ;i<n;i++) if(vis[i]) ans++;

        printf("%d\n",ans);

        for(int i = 0;i<n;i++) if(vis[i]) printf("%d\n",i+1);
    }
    return 0;
}

你可能感兴趣的:(【POJ1819】Disks——几何工具)