C++——贪心

 5745: 演讲大厅安排

描述

有一个演讲大厅需要我们管理,演讲者们事先定好了需要演讲的起始时间和中止时间。我们想让演讲大厅得到最大可能的使用。我们要接受一些预定而拒绝其他的预定,目标是使演讲者使用大厅的时间最长。假设在某一时刻一个演讲结束,另一个演讲就可以立即开始。

需要计算演讲大厅最大可能的使用时间。

输入

第一行为一个整数N,N≤5000,表示申请的数目。

以下n行每行包含两个整数p,k,0 ≤ p < k ≤ 30000,表示这个申请的起始时间和中止时间。

输出

一个整数,表示大厅最大可能的使用时间。

样例输入

 

12
1 2
3 5
0 4
6 8
7 13
4 6
9 10
9 12
11 14
15 19
14 16
18 20

样例输出

16

#include<bits/stdc++.h>
using namespace std;
struct node{
    int s,e,t; //s开始、e结束、t时间间隔 
};
node a[5010];
int n; //n个活动 
int b[5010][2]; //用来存储当前的活动 
bool comp(node x,node y)
{
    if(x.t==y.t)return x.s<y.s;
    else return x.t>y.t; //时间间隔大的优先 
} 
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i].s>>a[i].e;
        a[i].t = a[i].e - a[i].s; //时间间隔 = 结束-开始 
    }
    sort(a+1,a+1+n,comp); //排序 
    int time = 0,x,y,num = 1; //time最大使用时间,x,y是当前开始结束时间 
    for(int i=1;i<=n;i++)
    {
        int f = 1;
        for(int j=1;j<=num;j++) //循环当前已选的活动
        {
            if((a[i].s>b[j][0]&&a[i].s<b[j][1])||(a[i].e>b[j][0]&&a[i].e<b[j][1])) //右交集或者左交集
            {
                f = 0;
                break;
            } 
        }
        if(f==1)
        {
            time+=a[i].t;
            num++;
            b[num][0] = a[i].s;
            b[num][1] = a[i].e;
        }
    } 
    cout<<time; 
     return 0;
}
//5745 
View Code

 

5927: 线段

描述

 

 

在一个数轴上有n条线段,现选取其中k条线段使得这k条线段两两没有重叠部分(端点可以重合),问最大的k为多少?

 

 

输入

 

 

第一行为一个正整数n,下面n行每行2个整数ai,bi,描述每条线段。

对于20%的数据,n≤10。

对于50%的数据,n≤1000。

对于70%的数据,n≤100000。

对于100%的数据,n≤1000000, 0≤ai<bi≤1000000。

 

 

输出

 

 

输出文件仅包括1个整数,为k的最大值。

 

 

样例输入

 

3
0 2
2 4
1 3

样例输出

 2
#include<bits/stdc++.h>
using namespace std;
struct node{
    int s,e;
};
node a[1000005];
bool comp(node x,node y)
{
    return x.e>y.e;
}
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
        scanf("%d %d",&a[i].s,&a[i].e);
    sort(a+1,a+1+n,comp);
    int k = 1,x = a[1].s,y = a[1].e;
    for(int i=2;i<=n;i++)
    {
        if(a[i].e <= x) //找到下一个非重叠区间 
        {
            x = a[i].s;
            y = a[i].e;
            k++;
        }
        else if(a[i].s>=x && a[i].e<=y) //替换为更小的区间ai 
        {
            x = a[i].s;
            y = a[i].e;
        }
    }
    cout<<k;
     return 0;
}
View Code

 

5946: 区间选点问题

描述

 

 

给定x轴上的n个闭区间[ai, bi],选取尽可能少的点,使得每个闭区间至少有一个点(不同区间所含的点可以是同一个)。

 

 

输入

 

 

第一行为正整数n(n<=1000000),表示闭区间个数。

接下来有n行,每行两个整数ai和bi,表示第i个区间的起始位置。

 

 

输出

 

 

输出最少的点数。

 

 

样例输入

 

3
1 4
2 6
5 7

样例输出

 2
#include<bits/stdc++.h>
using namespace std;
struct node{
    int s,e;
};
node a[1000005];
bool comp(node x,node y)
{
    return x.e<y.e; //从右边大的优先 
}
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
        scanf("%d %d",&a[i].s,&a[i].e);
    sort(a+1,a+1+n,comp);
    int k = 1,x = a[1].s,y = a[1].e; //k选点数 
    for(int i=2;i<=n;i++)
    {
        if(y < a[i].s) 
        {
            k++;
            y = a[i].e;
        }
    }
    cout<<k;
     return 0;
}
View Code

 

1004: 渊子赛马

描述

 

 

赛马是一古老的游戏,早在公元前四世纪的中国,处在诸侯割据的状态,历史上称为“战国时期”。在魏国作官的孙膑,因为受到同僚庞涓的迫害,被齐国使臣救出后,到达齐国国都。
赛马是当时最受齐国贵族欢迎的娱乐项目。上至国王,下到大臣,常常以赛马取乐,并以重金赌输赢。田忌多次与国王及其他大臣赌输赢,屡赌屡输。一天他赛马又输了,回家后闷闷不乐。孙膑安慰他说:“下次有机会带我到马场看看,也许我能帮你。”
孙膑仔细观察后发现,田忌的马和其他人的马相差并不远,只是策略运用不当,以致失败。
比赛前田忌按照孙膑的主意,用上等马鞍将下等马装饰起来,冒充上等马,与齐王的上等马比赛。第二场比赛,还是按照孙膑的安排,田忌用自己的上等马与国王的中等马比赛,在一片喝彩中,只见田忌的马竟然冲到齐王的马前面,赢了第二场。关键的第三场,田忌的中等马和国王的下等马比赛,田忌的马又一次冲到国王的马前面,结果二比一,田忌赢了国王。
就是这么简单,现在渊子也来赛一赛马。假设每匹马都有恒定的速度,所以速度大的马一定比速度小的马先到终点(没有意外!!),相同则算对手赢。最后谁赢的场数多于一半(不包括一半),谁就是赢家(可能没有赢家)。渊子有N(1≤N≤1000)匹马参加比赛。对手的马的数量与渊子马的数量一样,并且知道所有的马的速度。聪明的你来预测一下这场世纪之战的结果,看看渊子能否赢得比赛。

 

 

输入

 

 

输入有多组测试数据。
每组测试数据包括3行:
第一行输入N(1≤N≤1000)。表示马的数量。
第二行有N个整型数字,即渊子的N匹马的速度。
第三行有N个整型数字,即对手的N匹马的速度。
当N为0时退出。

 

 

输出

 

 

若通过聪明的你精心安排,如果渊子能赢得比赛,那么输出“YES”。
否则输出“NO”。

 

 

样例输入

 

5
2 3 3 4 5
1 2 3 4 5
4
2 2 1 2
2 2 3 1
0

样例输出

YES
NO

#include<bits/stdc++.h>
using namespace std;
int n;
int a[1005],b[1005];
int y;
int main()
{
    while(cin>>n,n) //多组数据输入,以0结束 
    {
        for(int i=1;i<=n;i++)cin>>a[i];
        for(int i=1;i<=n;i++)cin>>b[i];
        sort(a+1,a+1+n);
        sort(b+1,b+1+n);
        int i = 1,j = 1;
        y = 0;
        while(i<=n && j<=n) //当两边都还有马可以比较时 
        {
            if(a[i]>b[j]) //a的第i头马比b的第j头马速度快
            {
                y++; i++; j++;
            } 
            else{
                i++;
            }
        }
        if(y>n*1.0/2)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
     return 0;
}
View Code

 

posted @ 2022-12-24 10:15  CRt0729  阅读(183)  评论(0编辑  收藏  举报