AcWing第62场周赛题解

AcWing第62场周赛地址

4500. 三个元素

题目

给定一个长度为 n n n 的数组 r 1 , r 2 , … , r n r_1,r_2,…,r_n r1,r2,,rn

请你找到其中的三个元素 r a , r b , r c r_a,r_b,r_c ra,rb,rc,使得 r a < r b < r c r_a < r_b < r_c ra<rb<rc 成立。

思路

先记录一个结构体数组 a a a ,包含元素的值和下标。

然后按元素的值 s o r t sort sort 排序一下,使得 r a ≤ r b ≤ r c r_a \le r_b \le r_c rarbrc 成立。

最后记录元素值只出现一次的元素,使得 r a < r b < r c r_a < r_b < r_c ra<rb<rc 成立。

判断非重复的元素的个数是否大于等于 3 3 3 , 是则输出前三个记录的元素的下标,否则输出 − 1 − 1 − 1 -1 -1 -1 111

C o d e Code Code

#include<bits/stdc++.h>
using namespace std;
int n;
struct node
{
    int id,num;
}a[3001];
bool cmp(node a,node b)
{
    return a.num<b.num;
}
int s[3001],len;
int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>a[i].num;a[i].id=i;
    }
    sort(a+1,a+n+1,cmp);
    for(int i=1; i<=n; i++)
    {
        if(a[i].num!=a[i-1].num)
        {
            s[++len]=a[i].id;
        }
    }
    if(len<3)cout<<"-1 -1 -1"<<endl;
    else 
    cout<<s[1]<<" "<<s[2]<<" "<<s[3]<<endl;
}

4501. 收集卡牌

题目

某干脆面厂商在每包面中都放置有一张武将卡。

武将卡共分为 n n n 种,编号 1 ∼ n 1 \sim n 1n

当集齐 1 ∼ n 1 \sim n 1n 号武将卡各一张时,就可以拿它们去换大奖。

为了换大奖,李华先后购买了 m m m 包该品牌的干脆面。

其中第 i i i 包面中包含的武将卡的编号为 a i a_i ai

每当买完一包面,得到该面赠送的武将卡后,李华都会审视一遍自己手中的全部卡牌。

如果此时自己现有的卡牌能够凑齐全部武将卡,那么他就会立即将每种武将卡都拿出一张,并将拿出的卡牌寄给厂商,用来换奖。

请你分析李华购买干脆面的整个过程并计算购买完每一包面后,李华能否凑齐全部武将卡用来换奖。

注意,每次换奖都需要消耗卡牌,消耗掉的卡牌就不属于他了。

思路

设换了 n o w now now 次奖, s x s_x sx 为卡牌数量大于等于 x x x 的卡牌种类的个数(不换一次奖)。

每收集一张卡牌 a i a_i ai ,卡牌 a i a_i ai 的数量 t [ a i ] t[a_i] t[ai] 加一,卡牌数量大于等于 t [ a i ] t[a_i] t[ai] 的卡牌种类 s [ t [ a i ] ] s[t[a_i]] s[t[ai]] 1 1 1 t [ a i ] t[a_i] t[ai] 已经加过一)。

s n o w + 1 = = n s_{now+1} == n snow+1==n ,则表示可以换第 n o w + 1 now + 1 now+1 次奖,输出 1 1 1 n o w now now 加一。

否则输出 0 0 0

C o d e Code Code

#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[100001];
int s[100001];
int now,t[100001];
int main()
{
    cin>>n>>m;
    for(int i=1; i<=m; i++)
    {
        cin>>a[i];
        t[a[i]]++;
        s[t[a[i]]]++;
        if(s[now+1]==n)
        {
            cout<<1;now++;
        }
        else cout<<0;
    }
}

4502. 集合操作

题目

给定一个由正整数(最初为空)组成的多重集 S S S。多重集表示可能存在重复元素的集合。

请你对该集合执行 Q Q Q 次操作,操作分为两种:

  • 增加操作,格式为 1 x,将一个正整数 x x x 加入到集合 S S S 中。数据保证, x x x 不小于当前 S S S 中的任何元素。
  • 询问操作,格式为 2,找到一个当前 S S S 的子集 s s s ,要求 m a x ( s ) − m e a n ( s ) max(s)-mean(s) max(s)mean(s) 的值应尽可能大,输出 m a x ( s ) − m e a n ( s ) max(s)-mean(s) max(s)mean(s) 的最大可能值。 m a x ( s ) max(s) max(s) 表示 s s s 中最大元素的值, m e a n ( s ) mean(s) mean(s) 表示 s s s 中所有元素的平均值。

思路

数据保证, x x x 不小于当前 S S S 中的任何元素。

其实自己在比赛的思路是正确的,但是没看到题目的数据保证就没写这一题,然后窝就去写另外两题的题解了(在比赛结束后才提交题解)。

大小为 n o w now now 的子集一定为 前 n o w − 1 now-1 now1 个元素(使平均值最小)和第 n n n 个元素(使子集的最大值最大)。

x x x 个数字的平均值可以用前缀和预处理。

C o d e Code Code

#include<bits/stdc++.h>
using namespace std;
double sum[500001],a[500001];
int Q,now=1,n;
int main()
{
  cin>>Q;
  while(Q--)
  {
    int op;
    cin>>op;
    if(op==1)
    {
      cin>>a[++n];
      sum[n]=a[n]+sum[n-1];
    }
    else
    {
      while(now<n&&a[n]-((sum[now]+a[n])/(now+1))>a[n]-((sum[now-1]+a[n])/now))now++;
      printf("%.6lf\n",a[n]-((sum[now-1]+a[n])/now));
    }
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值