移除木板

题目描述
创意班机房的地板要翻新啦,营长搬来了许多长短不一的木板。手痒的LZY趁大家不注意,把所有的木板叠在了一起,并且给大家提出了一个问题:我们最少需要移除多少块木板,使剩下的木板互相不重叠?作为ACMer的你,可以写个程序计算一下吗?
输入
测试样例由多组测试数据组成。每组测试数据第一行输入一个正整数n ( 1 <= n <= 10000 ),接下来 n行每行输入两个正整数,a,b ( 1 <= a , b <= 10000 )代表每块木板的起始坐标和最终坐标。
输出
输出每组测试样例最少需要移除的木板数量
样例输入 Copy
4
1 2
2 3
3 4
1 3
3
1 2
1 2
1 2
2
1 2
2 3
样例输出 Copy
1
2
0
解题思路:
我是用贪心的发法题目大概意思,由 N 块木板重叠在一起,我们要怎么得到
最少移除的木板数量呢?其实我们不妨转换一下问题,我们先求
出有最多多少块木板可以平铺在一层,然后相减即可得到答案。
求出最多有多少块木板可以平铺在一起非常简单,利用贪心的思
想即可。我们先定义一个结构体存储每块木板的起始点和终结点,
然后按照终结点从小到大排序,只有终结点越小的,才有可能容
得下更多的木板。在每次选择中,木板的结尾最为重要,选择的
木板结尾越小,留给后面的木板的空间越大,那么后面能够选择
的木板个数也就越多。所以按木板的结尾进行排序,每次选择结
尾最小,并且和前一个木板不重叠的木板:

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
struct s{
	int l;
	int r;
} a[10005];
bool q1(s n,s m){
	return n.r<m.r;
}
int main(){
	int n;
	while(~scanf("%d",&n)){
		for(int i=1;i<=n;i++){
			int l,r;
			scanf("%d%d",&l,&r);
			if(r<l){//里面的数据不一定都是 l<r 所以我们这边要进行一个判定;
				a[i].l=r;
				a[i].r=l;
			}else {
				a[i].l=l;
				a[i].r=r;
			}
		}
		sort(a+1,a+1+n,q1);//这里按 终点 来排序 小的在前大的在后
		int ans=0,cnt=1;
		//下面是第一组样例的排序结果
//		1 2 -> 1 2
//		2 3 -> 2 3
//		3 4 -> 1 3
//		1 3 -> 3 4
		for(int i=2;i<=n;i++){
			if(a[cnt].r<=a[i].l){
				cnt=i;
				//当结束的位置  小于等于 下一个初始的位置 就进到下一个;如果是大于ans就++;
			}else ans++;
		}
		cout<<ans<<endl;	
	} 
	return 0;
} 
发布了17 篇原创文章 · 获赞 0 · 访问量 388

猜你喜欢

转载自blog.csdn.net/fatsnake_piao/article/details/104768517