信息學奧賽一本通 1951:【10NOIP普及組】導彈攔截(思維、枚舉)

題目鏈接:點擊這裏
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
首先輸入兩套導彈系統的座標。

然後每讀入一對座標,就分別算出它距離第一套系統和第二套系統的距離。

按照距離第一套系統的遠近從大到小排一遍序,接下來問題就是怎麼確定第二套系統的半徑?

按距第一套系統的遠近從大到小排好序後,我們從頭開始向後枚舉分界點,分界點右邊導彈的歸第一套系統 (因爲右邊的數都小於分界點),左邊的第二套系統 (即從左邊選出最大的那個),然後在這些枚舉中取最小值就可以得到答案。

代碼如下:

#include<iostream>
#include<algorithm>
#include<string>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>

using namespace std;
typedef long long ll;
const int MOD = 10000007;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const int maxn = 100010;

struct node
{
	int x,y;	//導彈的座標
	int dis1,dis2;	//dis1,dis2分別表示導彈到第一套系統、第二套系統的距離 
}a[maxn];

bool cmp(node a, node b)
{
	return a.dis1>b.dis1;
} 

int main()
{
	int x1, y1, x2, y2;
	scanf("%d%d%d%d", &x1, &y1, &x2, &y2);	//輸入兩套導彈系統的座標 
	int n, x, y;
	scanf("%d",&n);		
	for(int i=0;i<n;i++)
	{
		scanf("%d%d",&a[i].x, &a[i].y);
		a[i].dis1 = (x1-a[i].x)*(x1-a[i].x) + (y1-a[i].y)*(y1-a[i].y);
		a[i].dis2 = (x2-a[i].x)*(x2-a[i].x) + (y2-a[i].y)*(y2-a[i].y);
	}
	
	sort(a, a+n, cmp);
	int r1;
	int r2 = -INF;
    int ans = INF;
    for(int i=0;i<=n;i++)
    {
        r1 = a[i].dis1;	//右邊歸第一套系統 
        r2 = max(r2, a[i-1].dis2);	//左邊歸第二套系統 
        ans = min(ans, r1+r2);	//更新ans 
    }
    
	printf("%d\n", ans);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章