【2014年鄞州区】小幸福(e.pas/c/cpp)

题目描述:

有n个小朋友,他们商量在保证作业做完的前提下去玩。第i个小朋友的可以玩耍时间为Si~ Ti。这里Si~Ti
表示的是时间段,比如Si=2,Ti=4,那么意味着这位小朋友在时刻1不能玩,时刻2、3、4可以去玩,时刻4以后都不能出去玩。如果在某个时刻,在一起玩的小朋友个数不少K个,那么这一时刻就是幸福的。现在你要求出所有幸福的时刻长度。

输入

三行 第一行:n k  (n个小朋友,一起玩的小朋友达到k个为幸福)
第二行:S1 S2 ... Sn
第三行:T1 T2 ... Tn

输出

一行:幸福时刻的长度

样例输入
4 3
1 2 2 4
5 2 4 6

样例输出
2

数据范围限制

50% n<=1000 1<=Si<=Ti<=1000
100% n<=100000 1<=Si<=Ti<=1000000000

提示

时刻                1  2  3  4  5  6
第一个小朋友玩耍时间:X  X  X  X  X
第二个小朋友玩耍时间:   X
第三个小朋友玩耍时间:   X  X  X
第四个小朋友玩耍时间:         X  X  X
第2分钟和第4分钟一起玩耍的小朋友达到了3个所以是幸福的时刻,幸福时刻长度为2。

50分思路:

这题50分思路还是计较简单的, 直接用一个数组把所有时刻的人数存入,最后再判断,每个时刻如果大于k,那ans++。

代码:

#include<bits/stdc++.h>
using namespace std;
int n,k,s[1000001],t[1000001],ans,bz[1000001];
int main()
{
	freopen("e.in","r",stdin);
	freopen("e.out","w",stdout);
	cin>>n>>k;
	for(int i=1;i<=n;i++)
		cin>>s[i];
	for(int i=1;i<=n;i++)
		cin>>t[i];
	for(int i=1;i<=n;i++)
		for(int j=s[i];j<=t[i];j++)
			if(bz[j]==-1) continue;
			else
			{
				bz[j]++;
				if(bz[j]>=k) bz[j]=-1,ans++;
			}
	cout<<ans;
	fclose(stdin);
	fclose(stdout);
	return 0;
}

加了线段数优化的代码:

#include<bits/stdc++.h>
using namespace std;
int sum[10000005]={};
int n,k;
int main()
{
	freopen("e.in","r",stdin);
	freopen("e.out","w",stdout);
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++)
	{
		int x;
		scanf("%d",&x);
		sum[x]++;
	}
	int o=-1;
	for(int i=1;i<=n;i++)
	{
		int x;
		scanf("%d",&x);
		if(x>o)o=x;
		sum[x+1]--;
	}
	int cnt=0,s=0;
	for(int i=0;i<=o;i++)
	{
		cnt+=sum[i];
		if(cnt>=k)
			s++;
	}
	printf("%d
",s);
	return 0;
}

100分思路:

这是50分做法的改编,将一个个的时间,改成以变化为分隔的时间段,大大加速了时间。

把每次变化(也就是s和t数组)合在一起排序,加上标记,每次变化,人数就变化,当人数满足幸福是,加上这次变化到下次变化前这个时间段。

核心代码:


	if(bj[i]==0) re++;
	if(bj[i]==1) re--;
	if(re>=k) ans+=a[i+1]-a[i]; //1<=i<=2*n

再加上快排,标记,我们就能开始打代码。

代码:

#include<bits/stdc++.h>
using namespace std;
int n,k,a[200010],bj[200010],re,ans; 
void qsort(int i,int j)
{
	int l=i,r=j,mid=a[(i+j+1)/2];
	while(i<=j)
	{
		while(a[i]<mid) i++;
		while(a[j]>mid) j--;
		if(i<=j)
		{
			a[0]=a[i];
			a[i]=a[j];
			a[j]=a[0];
			bj[0]=bj[i];
			bj[i]=bj[j];
			bj[j]=bj[0];
			i++; j--;
		}
	}
	if(l<j) qsort(l,j);
	if(i<r) qsort(i,r);
}
int main(){
	freopen("e.in","r",stdin);
	freopen("e.out","w",stdout);
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		bj[i]=0;
	}
	for(int i=1;i<=n;i++){
		scanf("%d",&a[n+i]);
		a[n+i]+=1;
		bj[n+i]=1;
	}
	qsort(1,2*n);
	for(int i=1;i<=2*n;i++){
		if(bj[i]==0) re++;
		if(bj[i]==1) re--;
		if(re>=k) ans+=a[i+1]-a[i];
	}
	printf("%d",ans);
	fclose(stdin);
	fclose(stdout);
	return 0;
}

写博不易,请发现问题的大佬提出。

代码保证正确,请留赞再走。

原文地址:https://www.cnblogs.com/2020-zhy-jzoj/p/13159910.html