noip 2010 導彈攔截(枚舉貪心)

題目描述

經過11 年的韜光養晦,某國研發出了一種新的導彈攔截系統,凡是與它的距離不超過其工作半徑的導彈都能夠被它成功攔截。當工作半徑爲0 時,則能夠攔截與它位置恰好相同的導彈。但該導彈攔截系統也存在這樣的缺陷:每套系統每天只能設定一次工作半徑。而當天的使用代價,就是所有系統工作半徑的平方和。

某天,雷達捕捉到敵國的導彈來襲。由於該系統尚處於試驗階段,所以只有兩套系統投入工作。如果現在的要求是攔截所有的導彈,請計算這一天的最小使用代價。

【提示】

兩個點(x1, y1)、(x2, y2)之間距離的平方是(x1−;; x2)^2+(y1−;;y2)^2。

兩套系統工作半徑r1、r2 的平方和,是指r1、r2 分別取平方後再求和,即r1^2+r2^2。

【樣例 1 說明】

樣例1 中要攔截所有導彈,在滿足最小使用代價的前提下,兩套系統工作半徑的平方分

別爲18 和0。

【樣例2 說明】

樣例中的導彈攔截系統和導彈所在的位置如下圖所示。要攔截所有導彈,在滿足最小使用代價的前提下,兩套系統工作半徑的平方分別爲20 和10。

【數據範圍】

對於10%的數據,N = 1

對於20%的數據,1 ≤ N ≤ 2

對於40%的數據,1 ≤ N ≤ 100

對於70%的數據,1 ≤ N ≤ 1000

對於100%的數據,1 ≤ N ≤ 100000,且所有座標分量的絕對值都不超過1000。

輸入格式

第一行包含4 個整數x1、y1、x2、y2,每兩個整數之間用一個空格隔開,表示這兩套導

彈攔截系統的座標分別爲(x1, y1)、(x2, y2)。

第二行包含1 個整數N,表示有N 顆導彈。接下來N 行,每行兩個整數x、y,中間用

一個空格隔開,表示一顆導彈的座標(x, y)。不同導彈的座標可能相同。

輸出格式

輸出只有一行,包含一個整數,即當天的最小使用代價。

【輸入輸出樣例1】
0 0 10 0
2
-3 3
10 0


【輸入輸出樣例2】
0 0 6 0
5
-4 -2
-2 3
4 0
6 -2
9 1

【輸入輸出樣例1】
18


【輸入輸出樣例2】
30

想法:對於兩個機器。我們可以枚舉他們的半徑來求解,但是半徑的範圍很大啊

但是仔細發現可以知道,當我們分配完以後對於a的半徑來說,肯定是某一個導彈與a點的距離。

所以,我們就可以枚舉這個半徑,這個半徑也就是s1,那麼對於此時的r2就是這個點後面所有點的最大值,不斷更新就好了


代碼

#include <iostream>
#include<string.h>
#include<algorithm>
using namespace std;

typedef struct
{
    int s1,s2;
} node;
bool cmp(node a,node b)
{
    return a.s1<b.s1;
}
int main()
{
    int x1,y1,x2,y2;
    cin>>x1>>y1>>x2>>y2;
    node a[100005];
    int n;
    cin>>n;
    for(int  i=1; i<=n; i++)
    {
        int xx,yy;
        cin>>xx>>yy;
        a[i].s1=(xx-x1)*(xx-x1)+(yy-y1)*(yy-y1);
        a[i].s2=(xx-x2)*(xx-x2)+(yy-y2)*(yy-y2);
    }
    sort(a+1,a+n+1,cmp);
    int r2=0;
    int minn=1000000000;
    for(int i=n; i>=0; i--)
    {
        r2=max(r2,a[i+1].s2);
        minn=min(minn,r2+a[i].s1);
    }
    cout<<minn<<endl;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章