题目链接
题意:
给定一个1e9*1e9的巨大棋盘,然后你有一只車,这个車和我们中国象棋一样,它可以直线行走,然后这个車在棋盘的左下角,但是有巫术制造了屏障来阻碍这个車,但是这个車可以移除一些障碍来使得他能到达最上层。
然后这些屏障有横有竖的,竖的直接就是在 x 轴的位置,横的,就有初始的位置X,长度L,和在某一高度上,就是H。
然后问,移除最少的屏障使得这个車到达顶层。
小结:
主要是别人告诉我的题意,然后成浩哥提醒我说,需要排序,我就想了想的确排序一下 可以解决很多问题了。
题解:
首先我们对于横的障碍来分析一下。
1、如果起点不是1,直接无视。(原因是,如果不是从1开始阻挡,其实車可以从1的位置溜走)
2、如果起点是1,且长度为1e9那么,ans++;(因为肯定是阻挡車到顶层)
3、如果起点为1,长度为任意,记录下来。
竖的障碍物,其实只要和横的构成一个方框把困住,那么必须要車一定要冲出这一层方框。
所以ans++;
综上所述,其实答案:
ans=长度为1e9起点为1的横板+构成横竖方框的个数。
胜营说用二分,其实我觉得直接贪心即可,复杂度O(n+m)
是因为,大家思考,我们枚举每一个合法的横板,
排序后,其实和排序前是一样,因为这个横板和竖板构成的二元关系固定的,不因为高度不同而导致不同的方框总数。
然后用最短的横板和最近的竖板构成的一组 使得ans++;
然后以此类推,枚举横板,如果能够着竖板就可以了。
贴上代码:
#include<bits/stdc++.h>
using namespace std;
const int inf=1e9;
const int N=1e5+10;
int main()
{
int n,m,a[N],b[N],ans=0,tot=0,cur;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(int i=0;i<m;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
if(x==1&&y==inf){
ans++;
}else if(x==1){
b[tot++]=y;
}
}
sort(a,a+n);
sort(b,b+tot);
cur=0;
for(int i=0;i<tot&&cur<n;i++){
//printf("%d %d %d\n",i,b[i],a[cur]);
if(b[i]>=a[cur]){
cur++;
ans++;
}
}
printf("%d\n",ans);
return 0;
}