AT1207 説明会 题解

题目传送门

更好的阅读体验?

我的思路:

  • 考了 \(0\) 分的选手不能参加面试,可以直接跳过

  • 其余选手的分数用数组存储,\(n\) 个分数全部输入后,将数组内的分数排序,方便以后进行分数线的判断。

  • 在输入会场的最大可容纳人数的同时计算分数线,可以减少 \(O(q)\) 的时空复杂度。

  • 当计算分数线时,有以下两种情况:

  • 面试会场可容纳所有分数不为零的选手,此时的分数线是 \(0\),代码实现为 if(k>=tot) cout<<0<<endl;
  • 面试会场容纳不下所有分数不为零的选手,分情况讨论:
  1. 分数线及以上的选手正好为 \(k_i\),此时分数线最低为低于分数线选手的最高分加 \(1\)
  1. 分数线及以上的选手低于 \(k_i\),不能再降低分数线,此时分数线最低为低于分数线选手的最高分加 \(1\)
  • 得通项公式:低于分数线选手的最高分加 \(1\),又因为是从小到大排序,所以,代码实现为 else cout<<a[tot-k]+1<<endl;
  • 注:a[tot-k+1]为会场正好满时最低的分数,此时低于分数线选手的最高分为 a[tot-k],分数线应为 a[tot-k]+1
  • 数据在 \(\operatorname{int}\) 范围内。

  • \(\operatorname{sort}\) 排序时,最坏情况下,时间复杂度为 \(O(n^2+n+q)\),不能通过本题,需要考虑归并排序,原理就不细讲了,不懂可以百度,并且可以做一下模板题

最坏情况下的复杂度:

时间:\(\operatorname{sort}\)\(O({n^2+n+q})\),归并排序为 \(O({n \log n+n+q})\)

空间:\(\operatorname{sort}\)\(O ({n})\),归并排序为 \(O ({2n})\)

sort代码:

#include<bits/stdc++.h>   //万能头文件  
using namespace std;
int n,q,a[100005],k,tot;
//tot为分数不为零的选手的数量 
int main()
{
	cin>>n;//n个选手 
	for(int i=1;i<=n;i++)
	{
		int x;
		cin>>x;
		if(x==0)  continue;//分数等于零时跳过 
		else
		{
			tot++;
			a[tot]=x;
		}//等于 a[++tot]=x;
	}
	sort(a+1,a+tot+1);//sort默认由小到大排序 
	cin>>q;//q次询问
	for(int i=1;i<=q;i++) 
	{
		cin>>k;
		if(k>=tot)  cout<<0<<endl;//套公式 
		else  cout<<a[tot-k]+1<<endl;//套公式 
	}
	return 0;
}

归并排序代码:

#include<bits/stdc++.h>   //万能头文件  
using namespace std;
int n,q,a[100005],k,tot;
//tot为分数不为零的选手的数量 
int t[100005];
void mergesort(int l,int r)//归并板子,可以背一下 
{
	if(l==r)  return;
	int mid=(l+r)/2;
	//等价于 int mid=(l+r)>>1;
	mergesort(l,mid);
	mergesort(mid+1,r);
	int i=l,j=mid+1,k=l;
	while(i<=mid&&j<=r)
	{
		if(a[i]<a[j])  t[k++]=a[i++];
		else  t[k++]=a[j++];
	}
	while(i<=mid)  t[k++]=a[i++];
	while(j<=r)  t[k++]=a[j++];
	for(i=l;i<=r;i++)  a[i]=t[i];
	return;
}
int main()
{
	cin>>n;//n个选手 
	for(int i=1;i<=n;i++)
	{
		int x;
		cin>>x;
		if(x==0)  continue;//分数等于零时跳过 
		else
		{
			tot++;
			a[tot]=x;
		}//等于 a[++tot]=x;
	}
	mergesort(1,max(tot,1));//改成归并排序 
	//可能tot为0,这时会RE,需要和1取最大值。 
	cin>>q;//q次询问
	for(int i=1;i<=q;i++) 
	{
		cin>>k;
		if(k>=tot)  cout<<0<<endl;//套公式 
		else  cout<<a[tot-k]+1<<endl;//套公式 
	}
	return 0;
}
posted @ 2025-02-08 16:46  Wy_x  阅读(24)  评论(0)    收藏  举报