DS实验题 Missile

题目:

提示:并没有精度问题。

原题 NOIP2010 导弹拦截

思路

设源点为A(x1, y1)和B(x2, y2)。

第一步,用结构体存节点,包括以下元素:
1.横坐标x
2.纵坐标y
3.节点和A的距离平方len1:len1 = (x-x1) * (x-x1) + (y-y1) * (y-y1)
4.节点和B的距离平方len2:len2 = (x-x2) * (x-x2) + (y-y2) * (y-y2)

其中3和4在输入的时候计算。

第二步,假设所有的点都在源点A的圆圈范围:根据与A点的距离平方len1的大小排序,使用sort,写个cmp。

第三步,从排好序的节点n(nodes[n])开始,遍历至nodes[1],进行以下工作:
(1)假设当前的节点nodes[i]加入源点B的圆圈,逐点维护圆圈B的半径平方的大小(若nodes[i].len2比r大,更新r):r(r初始化为0)。
(2)判断nodes[i]+r与先前的答案ans是否更小,是的话更新ans。

第三步结束之后即得到最优的答案。

代码

//
//  main.cpp
//  Missile_re
//
//  Created by wasdns on 16/11/23.
//  Copyright © 2016年 wasdns. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <algorithm>
#define maxn 1000000000;
using namespace std;

struct p
{
    int x, y;
    int len1;
    int len2;
};

p nodes[100005];

bool cmp(p p1, p p2)
{
    if (p1.len1 != p2.len1) {
        return p1.len1 < p2.len1;
    }
    
    return false;
}

int _max(int a, int b)
{
    if (a > b) {
        return a;
    }
    else return b;
}

int _min(int a, int b)
{
    if (a < b) {
        return a;
    }
    else return b;
}

int main()
{
    int x1, x2, y1, y2;
    cin >> x1 >> y1 >> x2 >> y2;
    
    int n, i;
    cin >> n;
    
    for (i = 1; i <= n; i++)
    {
        cin >> nodes[i].x >> nodes[i].y;
        
        nodes[i].len1 = (nodes[i].x - x1) * (nodes[i].x - x1)
        + (nodes[i].y - y1) * (nodes[i].y - y1);
        
        nodes[i].len2 = (nodes[i].x - x2) * (nodes[i].x - x2)
        + (nodes[i].y - y2) * (nodes[i].y - y2);
    }
    
    sort(nodes+1, nodes+n+1, cmp);
    
    int ans = maxn;
    int rlen = 0;
    
    for (i = n; i >= 1; i--)
    {
        rlen = _max(rlen, nodes[i+1].len2);
        
        ans = _min(ans, rlen + nodes[i].len1);
    }
    
    cout << ans << endl;
    
    return 0;
}

/*
 0 0 6 0
 5
 -4 -2
 -2 3
 4 0
 6 -2
 9 1 
*/

2016/11/24

posted @ 2016-11-24 14:33  Wasdns  阅读(154)  评论(0编辑  收藏  举报