算法设计第二次上机作业-贪心算法

算法设计第二次上机作业-贪心算法

区间合并

题目描述

给定 n 个闭区间 [ai; bi],其中i=1,2,…,n。任意两个相邻或相交的闭区间可以合并为一个闭区间。例如,[1;2] 和 [2;3] 可以合并为 [1;3],[1;3] 和 [2;4] 可以合并为 [1;4],但是[1;2] 和 [3;4] 不可以合并。

我们的任务是判断这些区间是否可以最终合并为一个闭区间,如果可以,将这个闭区间输出,否则输出no。

思路如下:

将各区间按照左边的节点大小进行排序,之后记录最右边的节点大小max_right。
如果最右边的节点大小小于下一个区间的左节点,则说明无法合并。
否则,将max_right更改为较大值。

AC的代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
#define Max 50005
struct inteval {
    int left;
    int right;
};
inteval inputs[Max];
int flag[Max];
int cmp(inteval input1, inteval input2) {
    
    return input1.left<input2.left;
}

int main(int argc, const char * argv[]) {
    // insert code here...
    int num, top = 0, pretop;
    queue<inteval> que;
    scanf("%d", &num);
    for(int i=0; i<num; i++) {
        scanf("%d%d", &inputs[i].left, &inputs[i].right);
    }
    sort(inputs, inputs+num, cmp);
    int maxright = inputs[0].right;
    int minleft = inputs[0].left;
    int flag = 0;
    for(int i=1; i<num; i++) {
        if(inputs[i].left > maxright) {
            cout<<"no"<<endl;
            flag = 1;
            break;
        }
        else if(inputs[i].right >= maxright) {
            maxright = inputs[i].right;
        }
    }
    if(flag == 0) {
        cout<<minleft<<" "<<maxright<<endl;
        
    }
    return 0;
}

Radar Installation

题目描述

在海岸线上建雷达,使得建的雷达数目最小,能够覆盖所有的岛屿。

思路如下:

将每个岛屿需要的雷达的区间计算出来,然后和区间调度的思路相同。
按照每个区间的右节点进行排序,如果该节点落在下一个区间里面,则不需要增加雷达,如果没有,则需要增加下一个雷达。

AC的代码如下:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#define Max 1005
using namespace std;
struct dis {
    double left;
    double right;
};
int cmp(dis inteval1, dis inteval2) {
    return inteval1.right<inteval2.right;
}

int main(int argc, const char * argv[]) {
    // insert code here...
    int n, d, x, y;
    dis intevals[Max];
    bool flag = true;
    int temp, no = 0;
    /*scanf("%d", &temp);
    double res = sqrt(pow(temp,2.0)-1);
    cout<<res<<endl;*/
    while(scanf("%d%d", &n, &d) && n!=0 && d!=0) {
        no++;
        flag = true;
        for(int i=0; i<n; i++) {
            scanf("%d%d", &x, &y);
            if(y > d) {flag = false; continue;}
            double temp_left = x-sqrt(pow(d,2.0)-pow(y,2.0));
            double temp_right = x+sqrt(pow(d,2.0)-pow(y,2.0));
            intevals[i].left = temp_left;
            intevals[i].right = temp_right;
        }
        if(flag == false) {
            cout<<"Case "<<no<<": -1"<<endl;
            continue;
        }
        sort(intevals, intevals+n, cmp);
        double max_right = intevals[0].right;
        int num = 1;
        for(int i=1; i<n; i++) {
            if(max_right < intevals[i].left) {
                max_right = intevals[i].right;
                num++;
            }
        }
        cout<<"Case "<<no<<": "<<num<<endl;
    }
    return 0;
}
微信扫码订阅
UP更新不错过~
关注
  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

请叫我迷妹

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值