水题(贪心)
(water)
Time Limit:1000ms Memory Limit:128MB
题目描述
LYK出了道水题。
这个水题是这样的:有两副牌,每副牌都有n张。
对于第一副牌的每张牌长和宽分别是xi和yi。对于第二副牌的每张牌长和宽分别是aj和bj。第一副牌的第i张牌能覆盖第二副牌的第j张牌当且仅当xi>=aj并且yi>=bj。(注意牌不能翻转)当然一张牌只能去覆盖最多一张牌,而不能覆盖好多张。
LYK想让两副牌的各n张一一对应叠起来。它想知道第二副牌最多有几张能被第一副牌所覆盖。
输入格式(water.in)
第一行一个数n。
接下来n行,每行两个数xi,yi。
接下来n行,每行两个数aj,bj。
输出格式(water.out)
输出一个数表示答案。
输入样例
3
2 3
5 7
6 8
4 1
2 5
3 4
输出样例
2
数据范围
对于50%的数据n<=10。
对于80%的数据n<=1000。
对于100%的数据1<=n<=100000,1<=xi,yi,aj,bj<=10^9。
#include<iostream> #include<cstdio> #include<algorithm> #define maxn 100010 using namespace std; int n,ans; struct node{ int x,y; bool operator < (const node c)const{ if(x!=c.x)return x<c.x; return y<c.y; } }a[maxn],b[maxn]; bool vis[maxn]; int qread(){ int i=0; char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch<='9'&&ch>='0')i=i*10+ch-'0',ch=getchar(); return i; } int find(node now){ int pos=n+1,res=n+1; int l=1,r=n; while(l<=r){ int mid=(l+r)>>1; if(b[mid].x<=now.x)pos=mid,l=mid+1; else r=mid-1; } if(pos==n+1)return pos; for(int i=pos;i>=1;i--) if(b[i].y<=now.y&&!vis[i]){vis[i]=1;res=i;break;} return res; } int main(){ freopen("water.in","r",stdin);freopen("water.out","w",stdout); // freopen("Cola.txt","r",stdin); n=qread(); for(int i=1;i<=n;i++)a[i].x=qread(),a[i].y=qread(); for(int i=1;i<=n;i++)b[i].x=qread(),b[i].y=qread(); sort(a+1,a+n+1);sort(b+1,b+n+1); for(int i=1;i<=n;i++){ int pos=find(a[i]); if(pos==n+1)continue; ans++; } printf("%d",ans); return 0; }