题目背景
快 noip 了,yyy 很紧张!
题目描述
现在各大 oj 上有 nn 个比赛,每个比赛的开始、结束的时间点是知道的。
yyy 认为,参加越多的比赛,noip 就能考的越好(假的)。
所以,他想知道他最多能参加几个比赛。
由于 yyy 是蒟蒻,如果要参加一个比赛必须善始善终,而且不能同时参加 22 个及以上的比赛。
输入格式
第一行是一个整数 nn,接下来 nn 行每行是 22 个整数 ai,bi (ai<bi)ai,bi (ai<bi),表示比赛开始、结束的时间。
输出格式
一个整数最多参加的比赛数目。
输入数据 1
3
0 2
2 4
1 3
输出数据 1
2
这道题有两种写法,但本质思路都相同
这道题没有明显算法,总体写法也不是很难,重点在于对排序应用的掌握:
话不多说,我们就来一起温习一下排序吧。
1.普通排序
sort(数组名+0/1,数组名+长度+0/1,判断规则)
这种排序方法编写容易,思路简单,但时间复杂度高,为n*log2n,在一些测试点数据较大的题目中要谨慎使用,本题需对还是和结束同时排序,所以不能使用
2.结构体排序
在sort排序之上引申出的排序,基本与sort排序相同、
结构体排序弥补了sort不能实现的功能,在本题中可以应用,写法如下:
struct node { int s,e; }; node a[1000005]; bool cmp(node x,node y) { return x.e<y.e; }
3.归并排序
主要思想为分治思想,将要排序的主体一分为二,不断拆分排序然后融合
归并排序有很多潜在特质,所以在很多难题中都会出现隐藏的应用,比如用来求逆序对……,比较难以分析,同时也是一种稳定的排序,时间复杂度为O(nlogn),模板如下
void msort(int s,int t) { if(s==t) return; int mid=(s+t)/2; msort(s,mid); msort(mid+1,t); int i=s,j=mid+1,k=s; while(i<=mid&&j<=t){ if(a[i]<=a[j]){r[k]=a[i];k++;i++;} else{r[k]=a[j];k++;j++;ans+=mid-i+1;} } while(i<=mid){r[k]=a[i];k++;i++;} while(j<=t){r[k]=a[j];k++;j++;} for(int i=s;i<=t;i++) a[i]=r[i]; }
4.快速排序
主体思想就是不断比较,交换……
是一种不稳定的排序,好的话是O(nlogn),坏的话是O(n^2),模板如下
void qsort(int x,int y) { int i,j,mid,t; i=x;j=y;mid=last[(x+y)/2]; while(i<=j){ while(last[i]<mid) i++; while(last[j]>mid) j--; if(i<=j){ t=last[j];last[j]=last[i];last[i]=t; t=began[j];began[j]=began[i];began[i]=t; i++; j--; } } if(x<j) qsort(x,j); if(i<y) qsort(i,y); }
这道题可以说是一个区间贪心,如图:
事实证明按后端点排序才能更多的完成
①结构体写法:
AC code:
#include <bits/stdc++.h>
using namespace std;
struct node
{
int s,e;
};
node a[1000005];
bool cmp(node x,node y)
{
return x.e<y.e;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].s>>a[i].e;
}
sort(a+1,a+1+n,cmp);
int b=a[1].e,ans=1;
for(int i=2;i<=n;i++){
if(a[i].s>=b){
ans++;
b=a[i].e;
}
}
cout<<ans;
return 0;
}
②快速排序写法:
#include<bits/stdc++.h>
using namespace std;
int began[1000005],last[1000005];
void qsort(int x,int y)
{
int i,j,mid,t;
i=x;j=y;mid=last[(x+y)/2];
while(i<=j){
while(last[i]<mid) i++;
while(last[j]>mid) j--;
if(i<=j){
t=last[j];last[j]=last[i];last[i]=t;
t=began[j];began[j]=began[i];began[i]=t;
i++;
j--;
}
}
if(x<j) qsort(x,j);
if(i<y) qsort(i,y);
}
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>began[i]>>last[i];
qsort(1,n);
int ans=0;
int t=-1;
for(int i=1;i<=n;i++){
if(began[i]>=t){
ans++;
t=last[i];
}
}
cout<<ans<<endl;
return 0;
}