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
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
样例输出
#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; }
5946: 区间选点问题
描述
给定x轴上的n个闭区间[ai, bi],选取尽可能少的点,使得每个闭区间至少有一个点(不同区间所含的点可以是同一个)。
输入
第一行为正整数n(n<=1000000),表示闭区间个数。
接下来有n行,每行两个整数ai和bi,表示第i个区间的起始位置。
输出
输出最少的点数。
样例输入
3
1 4
2 6
5 7
样例输出
#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; }
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; }