【NOIP普及组】2016年模拟考试(9.3)——笨笨的西瓜种植

二、笨笨的西瓜种植(watermelon.cpp) 

【题目描述】

笨笨种了一块西瓜地,但这块西瓜地的种植范围是一条直线的…… 笨笨在一番研究过后,得出了m个结论,这m个结论可以使他收获的西瓜最多。 笨笨的结论是这样的: 从西瓜地B处到E处至少要种植T个西瓜,这个范围的收获就可以最大化。 笨笨不想那么辛苦,所以他想种植的西瓜尽量少,而又满足每一个所得的结论。

【输入】

第一行两个数n,m0<n<=5000,0<=m<=3000),表示笨笨的西瓜地长n,笨笨得出m个结论。 

接下来m行表示笨笨的m个结论,每行三个数b,e,t1<=b<=e<=n,0<=t<=e-b+1

【输出】

 输出笨笨最少需种植多少西瓜。

【输入样例】

9 4
1 4 2
4 6 2
8 9 2
3 5 2

【输出样例】

5

------------------------------------------------------------------------------------------------------


此题和NOIP的整数区间十分像,只不过加了一个“长度”和“个数”,怎么处理呢?

它增加了一个长度n之后,我原来以为n没有任何卵用,但是,确实没有什么卵用

所以,我们只需要处理“个数”就行了:
处理个数嘛,就简单了,加个v数组存次数(个数),每次查一下,查到了就--,在进入循环时判断一下(v!=0)就行了。

就是整数区间的方法了:

按照“右端点”(输入中的e)进行排序,注意:当“右端点”一样时,一定要判断“左端点”(b)

然后,就是j从“右端点”开始,每次符合条件就进入,sum++,查后面的“区间”中有没有此数,有,v就--。

好像没说清楚……大家看代码吧:

#include<cstdio>
#include<algorithm>
using namespace std;
struct k
{
	int b;
	int e;
	int v;
}wl[3002];//定义结构体更方便
int n,m;
int v[5002];//这里的“v”和结构体里的“v”不同,是用来看第i块地有没有种西瓜,种了肯定就不能再种
int cmp(k x,k y)
{
	if(x.e!=y.e)
		return x.e<y.e;
	else
		return x.b<y.b;
}
int main()
{
	freopen("watermelon.in","r",stdin);
	freopen("watermelon.out","w",stdout);//文件输入输出
	scanf("%d%d",&n,&m);
	for(int i=0;i<m;i++)
		scanf("%d%d%d",&wl[i].b,&wl[i].e,&wl[i].v);
	sort(wl,wl+m,cmp);//本来我习惯自己“sort”,结果没“sort”出来
	int sum=0;
	for(int i=0;i<m;i++)
		for(int j=wl[i].e;j>=wl[i].b;j--)
			if(v[j]==0&&wl[i].v>0)//判断
			{
				sum++;
				v[j]=1;
				for(int k=i;k<m;k++)
					if(j<=wl[k].e&&j>=wl[k].b)//我之前傻到还加了一个for循环让p从b到e来比较……
						wl[k].v--;
			}
	printf("%d",sum);
	return 0;
}





 

posted @ 2016-09-08 13:11  ∑∞  阅读(269)  评论(0编辑  收藏  举报