求大佬解惑

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

Gray这周末会举办一个超棒的派对,许多知名人物都会出席。但你猜,谁收不到邀请?

派对会邀请曾经参加过校赛的参赛者们。我们假设,至今为止一共有 NNN 位参加过校赛的参赛者,他们的编号从 111 到 NNN 。如果一位参赛者第一次参加的校赛是第 iii 届校赛,则他被认为是第 iii 届参赛者。

第一届校赛只有一个人参加,他是编号为 111 的第一届参赛者。第二届及之后的每一届校赛的参赛者,都是被上一届的参赛者邀请来的。参赛者在第一次参加校赛后,可以邀请多个人参加下一届的校赛,但只会邀请还从未参加过校赛的人。一个人最多只会被邀请一次,就是说,不会出现同时有多个人邀请同一个人参加校赛的情况。其中,编号为 iii 的参赛者是被编号为 aia_iai​ 的参赛者邀请的。(特殊的, 111 号参赛者没有被人邀请过,所以 a1=0a_1 = 0a1​=0 ,代表邀请他的人不存在。)

如果一名参赛者被邀请来了派对,但他发现邀请他参加校赛的人没有被邀请来派对,他就会很难过。如果一名参赛者被邀请来了派对,但他发现有和他同届的参赛者没有被邀请来派对,他也会觉得很难过。至于 111 号参赛者?他有着伟大的性格,他总是很开心!

由于场地大小有限,Gray只能邀请部分参赛者来派对。但他希望派对上的所有人都不会感到难过,都能开心的参加派对!在这个基础上,他希望邀请尽可能多的人来参加派对。

现在有 QQQ 个场地可供选择,用以举办派队。如果选择在第 iii 个场地举办派对,因为场地大小限制,最多只能邀请 bib_ibi​ 个人。Gray想知道,如果选择在第 iii 个场地举办派对,在满足场地大小限制,且保证没有人会难过的前提下,最多只能邀请多少人参加派对?

输入描述:

第一行输入一个正整数 NNN ( 1≤N≤1051 \leq N \leq 10^{5}1≤N≤105 ),表示共有 NNN 位参赛者。

第二行输入 NNN 个正整数, a1,a2,a3…aNa_1,a_2,a_3 \dots a_Na1​,a2​,a3​…aN​ ( a1=0a_1 = 0a1​=0 ;对于任意 2≤i≤N2 \leq i \leq N2≤i≤N 满足 1≤ai≤i1 \leq a_i \leq i1≤ai​≤i ),其中 aia_iai​ 表示 iii 号参赛者是被 aia_iai​ 号参赛者邀请来参加校赛。

第三行输入一个正整数 QQQ ( 1≤Q≤1051 \leq Q \leq 10^{5}1≤Q≤105 ),表示共有 QQQ 个场地可供选择。

第四行输入 QQQ 个正整数, b1,b2,b3…bQb_1,b_2,b_3 \dots b_Qb1​,b2​,b3​…bQ​ (对于任意 1≤i≤N1 \leq i \leq N1≤i≤N 满足 1≤bi≤N1 \leq b_i \leq N1≤bi​≤N ),其中 bib_ibi​ 表示如果选择在第 iii 个场地举办派对,只考虑场地大小限制,最多只能邀请 bib_ibi​ 个人。

输出描述:

输出 QQQ 行,每行输出一个整数。其中,第 iii 行输出的整数,表示如果选择在第 iii 个场地举办派对,在满足场地大小限制,且保证没有人会难过的前提下,最多只能邀请多少人参加派对。

这个是通过了的代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[100010],n,q,b,mp[100010],c[100010],ma=0;
int main()
{
	ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
	cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        mp[i]=mp[a[i]]+1;ma=max(ma,mp[i]);
        c[mp[i]]++;
    }
    for(int i=1;i<=ma;i++){
        c[i]=c[i-1]+c[i];
    }
    cin>>q;
    while(q--){
        cin>>b;
        int p=lower_bound(c+1,c+1+ma,b)-c;
        if(c[p]>b)p--;
        cout<<c[p]<<'\n';
    }
	return 0;
}

这个是我的垃圾:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5;
int a[N+10],b[N+10];
int h[N+1];
int prefixSum[N+1]; // 添加一个前缀和数组

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    int n;
    cin >> n;
    
    for(int i=1;i<=n;i++)
    {
        cin >> a[i];
        h[a[i]]++;
    }
    prefixSum[0]=1;
    // 计算前缀和数组
    for (int i = 1,j=1; i <= N; i++) {
        prefixSum[i] = (prefixSum[i-1] + h[j]>i) ? prefixSum[i-1]:(prefixSum[i-1] + h[j]);
    	if(prefixSum[i]>prefixSum[i-1]) j++;
    }

    int q;
    cin >> q;
    for(int i=1;i<=q;i++)
    {
        cin >> b[i];
        cout<<prefixSum[b[i]]<<"\n";
    }
    return 0;
}

想知道我的代码为什么过不了

  • 21
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值