牛客周赛 Round 54 A~D

本期封面原图 画师アマネレイ

牛客周赛 Round 54

A - 清楚姐姐的糖葫芦

题意

数给定字符串中的o的个数

代码

#include <bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int main()
{
    string s;
    cin>>s;
    int cnt=0;
    for(char c:s)
    {
        if(c=='o')
            cnt++;
    }
    printf("%d\n",cnt);
    return 0;
}

B - 清楚姐姐买竹鼠

题意

一只竹鼠a元,三只竹鼠b元,问买x只竹鼠最少花多少钱

思路

首先判断单买三只的价格是否比b小,如果单买更划算就全部单买
不然的话就尽量三只三只买,然后再把剩下的单只单只买,这很好想到,但到这里你会发现只有90分,WA了一个点,还好这是IOI赛制,不用慌
如果买三只的价格特别低,那我其实可以再最后要买一只或者两只的时候多买几只凑三只买,当然也可以比较单买两只和三只的价格,但是我就直接写了个取最小值了

代码

#include <bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int main()
{
    ll a,b,x;
    cin>>a>>b>>x;
    ll ans=0;
    if(a*3<=b)
        ans=a*x;
    else
        ans=min((x/3)*b+(x%3)*a,b*(x/3+(x%3==0?0:1)));
    printf("%lld\n",ans);
    return 0;
}

C - 竹鼠饲养物语

题面

           \,\,\,\,\,\,\,\,\,\, 鼠鼠快速成长饲料一共分为 m m m 个等级,初始时全部竹鼠都是零级竹鼠,投喂一袋“鼠鼠快速成长饲料 I \rm I I ”可以升级为一级竹鼠,继续投喂“鼠鼠快速成长饲料 I I \rm II II ”可以升级为二级竹鼠,……。需要注意的是,你不能越级投喂,例如,向零级竹鼠投喂“鼠鼠快速成长饲料 I I \rm II II ”没有任何效果。

           \,\,\,\,\,\,\,\,\,\, 清楚一共有 n n n 袋饲料和无限多的零级竹鼠,问最多可以进行多少次有效投喂。

思路

很容易想到开桶记录每一个等级的饲料有多少,然后后面比前面多的话多出来的就不算,但是被1e9的范围吓唬回去了。但是仔细想一下,最多1e5袋,就算是最坏的情况也顶多升1e5级,后面等级的饲料其实我都不需要考虑,所以桶只需要开1e5就可以了

代码

#include <bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

int main()
{
    ll n,m;
    scanf("%lld%lld",&n,&m);
    ll st[100005];
    ll ans=0;
    memset(st,0,sizeof(st));
    for(int i=1;i<=n;i++)
    {
        ll x;
        scanf("%lld",&x);
        if(x<=100005)
            st[x]++;
    }
    for(int i=2;i<=min(m,100005ll);i++)
    {
        if(st[i]>st[i-1])
            st[i]=st[i-1];
    }
    for(int l=1;l<=min(m,100005ll);l++)
    {
        if(st[l]==0)
            break;
        ans+=st[l];
    }
    printf("%lld\n",ans);
    return 0;
}

D - 清楚姐姐跳格子

题面

           \,\,\,\,\,\,\,\,\,\, 清楚正在玩跳格子游戏。地上有 n n n 个格子,清楚一开始在 1 1 1 号格子,目标是 n n n 号格子。

           \,\,\,\,\,\,\,\,\,\, i i i 个格子上有一个数字 a i a_i ai ,清楚在这个格子上可以往左右两边选一个方向,然后选择 a i a_i ai 的一个正整数因子作为长度,进行一次跳跃,但是不可以跳出边界。

           \,\,\,\,\,\,\,\,\,\, 请问清楚最少跳多少步,就可以到达 n n n 号格子。

思路

一开始想的肯定是dfs,但是因数太多,一个点可以跳去好几个不同的位置,但是又只有1000个点,那么我们自然的就可以想到建邻接表,对每一个可以走的位置建有向边跑dijkstra,但是现在因数太多又是个问题。我们求一个数所有因数最快也需要 O ( n ) O(\sqrt{n}) O(n ),这里的a的数据范围又是1e18,肯定是不行的。但是有了上一题的经验,我们再仔细看一下,其实每个点我们只需要找1000内的因数就可以了,所以一样可以正常解决

代码

#include <bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
vector<int> G[1005];

int main()
{
    int n;
    scanf("%d",&n);
    vector<ll> a(n+1);
    for(int i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    for(int i=1;i<=n;i++)
    {
        int b=max(abs(n-i),abs(i-1));
        for(int j=1;j<=b;j++)
        {
            if(a[i]%j==0)
            {
                if(i+j<=n)
                    G[i].push_back(i+j);
                if(i-j>=1)
                    G[i].push_back(i-j);
            }
        }
    }
    ll ans=0;
    //dijkstra求1到n的最短路 以G[i]为邻接表
    vector<ll> dis(n+1,1e18);
    dis[1]=0;
    priority_queue<pll,vector<pll>,greater<pll>> q;
    q.push({0,1});
    while(!q.empty())
    {
        pll p=q.top();
        q.pop();
        int u=p.second;
        if(p.first>dis[u])
            continue;
        for(int v:G[u])
        {
            if(dis[v]>dis[u]+1)
            {
                dis[v]=dis[u]+1;
                q.push({dis[v],v});
            }
        }
    }
    ans=dis[n];
    printf("%lld\n",ans);
    return 0;
}
  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
牛客 a卷2022年第四季度的华为题目中,要求考生设计一种高效的数据结构,能够支持以下几种操作: 1. 添加一个元素 2. 删除一个元素 3. 查找是否存在某个元素 4. 返回元素的总数 该数据结构要求满足空间复杂度较小、时间复杂度较低、能够快速地进行查找和修改等多种操作。 想要编写这样一种数据结构,我们可以参考许多已有的经典算法数据结构,如二叉树、哈希表、红黑树等,通过综合利用它们的优点来实现这个问题的解决。 例如,我们可以通过哈希表来存储所有元素的值,并在每个哈希链表的元素中再使用红黑树来进行排序与查找。这样,我们既能够轻松地进行元素的添加和删除操作,也能够在查找较大数据范围和数量时保持较高的速度与效率。同时,由于使用了多个数据结构来协同完成这个问题,我们也能够在空间复杂度上适度地进行优化。 当然,在具体设计这个数据结构的过程中,我们还需要考虑一些实践中的细节问题,例如如何避免哈希冲突、如何处理数据丢失与被删除元素所占用的空间等问题,这都需要相应的算法与流程来进行处理。 总体来看,设计这种支持多种操作的高效数据结构,需要我们具备丰富的算法知识和编程实践能力,同时需要我们在具体处理问题时能够将多种算法数据结构进行有效地结合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值