AT1207 説明会 题解

· · 题解

题目传送门

更好的阅读体验?

我的思路:

  • 面试会场可容纳所有分数不为零的选手,此时的分数线是 0,代码实现为 if(k>=tot) cout<<0<<endl;

  • 面试会场容纳不下所有分数不为零的选手,分情况讨论:

  1. 分数线及以上的选手正好为 k_i,此时分数线最低为低于分数线选手的最高分加 1

  2. 分数线及以上的选手低于 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}),归并排序为 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;
}