Poj-1328 二维化一维 典型贪婪算法

题意大概是x轴上方是海洋,海洋上分布着一些岛屿(用点坐标表示),你呢想在岸上安装雷达,使得雷达能扫到岛屿(即在雷达的范围内),求安装雷达的最小数量^-^

Poj-1328
#include<cstdio>
#include<algorithm>
#include<cmath>
const int INF = 1000000000;
using namespace std;
struct  Interval {      //interval是区间的意思
    double left, right;
};
const int max_island = 1000 + 10;
Interval the_interval[max_island];
int the_num;
double the_r;
bool cmp(const Interval& a, const Interval& b) { //排序函数
    if (a.right == b.right)
        return a.left >= b.left;
    return a.right < b.right;
}
int main() {
    int the_case = 1;
    while (scanf("%d%lf", &the_num, &the_r) == 2) {
        if (the_num == 0 && the_r == 0)
            break;
        double point_x, point_y;
        bool if_out_r = false;
        for (int i = 0; i < the_num; i++) {
            scanf("%lf%lf", &point_x, &point_y);
            if (point_y > the_r) {//如果离海岸太远,超出雷达半径,我劝你还是放弃吧
                if_out_r = true;
            }
            else {
                the_interval[i].left = point_x - sqrt(pow(the_r, 2) - pow(point_y, 2));
                the_interval[i].right = point_x + sqrt(pow(the_r, 2) - pow(point_y, 2));
            }
        }
        if (if_out_r) {
            printf("Case %d: -1\n", the_case++);
        }
        else {
            sort(the_interval, the_interval + the_num, cmp);
            double most_left = -INF; //double 我写成int找了很久,最大允许的左边区间点
            int the_need_radar = 0;
            for (int i = 0; i < the_num; i++) {
                if (the_interval[i].left > most_left) {
                        most_left = the_interval[i].right;
                        the_need_radar++;
                }
            }
            printf("Case %d: %d\n", the_case++, the_need_radar);
        }
    }
    return 0;
}

总结:
1.防止思路错误——我先前以为是像平移法一样把圆往右移,依次计算,导致我花了很长一段时间来写
2.审题要仔细,特别是那些对变量的描述的词汇,特别注意如数据类型,范围,输出格式······
3.编程时先写主函数,把框架先写好,遇到阻碍,在写细节。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值