可达鸭模拟赛(二)补题报告S10891栾珺琦

一.比赛分数:

共四题,满分400,第一题30分,第二题30分,第三题10分,第四题10分,共得80分。

二.比赛过程:

第一题代码写的很长,就是用for循环if判断sort从大到小排序然后取第一个最大的数,数组开的挺大,还有双层for循环,时间超限,并且我感觉情况没有列完。

第二题没有判断向右移动 1 个格子这个条件,只把题目中样例的情况写上了,和x和y相同的情况。

第三题没大读明白题,在老师讲了后,就知道了,模拟赛时,是蹭的样例。

第四题没大读明白题,输入也是后来才弄明白的,模拟赛时,是蹭的样例。

三.题解报告:

(1)第一题:独木桥

情况:赛中30分,已补题

题意:独木桥上的人数 n,独木桥的长度 L , 第 i个人的初始位置到独木桥左端点的距离a​i​​ 米,计算出所有人同时出发,全部都离开独木桥所需的最短时间。

题解:可以取中间值,然后左右两边分别向对面走,判断时间最长的那个输出。

赛后总结:感觉这道题自己想得太复杂,并且在自己的代码里在测试的时候,桥是奇数时,输出的数就好像不大对,但相对来说很简单。

AC代码:

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<vector>
using namespace std;
int n,l,x;
int ans=0;
int main(){
    cin>>n>>l;
    for(int i=0;i<n;i++){
        scanf("%d",&x);
        ans=max(ans,min(x,(l-x)));
    }
    cout<<ans<<endl;
    return 0;
}

(2)第二题:移动棋子

情况:赛中30分,已补题

题意:操作 1 :向右移动 1 个格子。
           操作 2 :从当前棋子所在的 a 号格子,直接跳到 -a 号

           计算把棋子从 x号格子移动到 y 号格子需要的最少操作次数。

题解:三个主要判断,第一个是x和y负数的,第二个是x和y正数的,第三个是x和y等于0的,里面是判断x和y谁大的。

赛后总结:我多判断了x和y都是0的情况。

AC代码:

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<vector>
using namespace std;
long long x,y,ans;
int main(){
    cin>>x>>y;
    if (x*y<0){
        ans=abs(abs(x)-abs(y))+1;
    }
    else if (x*y>0){
        if (x>y){
            ans=x-y+2;
        }
        else if (x<y){
            ans=y-x;
        }
    }
    else {
        ans=abs(x-y);
        if (x>y){
            ans=ans+1;
        }
    }
    cout<<ans<<endl;
    return 0;
}

(3)第三题:动物园

情况:赛中10分,已补题

题意:最少需要花费多少钱买门票才能看到所有种类的动物(同
一种动物可能不止看一个)。注意:只能买一张门票。

题解:利用了双指针的思想,l和r在一个下标上,假如动物种类数量是5,l和r往后移动,全部包含5种动物种类数后,是最优解后,场数*10,l和r再往后移, 再找到包含5种动物种类数,一直到r到n,输出最优解。

赛后总结:赛中没看懂,赛后老师讲后就懂了。

AC代码:

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<vector>
using namespace std;
int n,m,a[1000005],vis[1000005];
int main(){
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    int l=1,r=0,cnt=0,ans=0x3f3f3f3f;
    while (r<n){
        while (cnt<m&&r<n){
            r++;
            vis[a[r]]++;
            if (vis[a[r]]==1){
                cnt++;
            }
        }
        while (cnt==m){
            ans=min(ans,r-l+1);
            vis[a[l]]--;
            if (vis[l]==0){
                cnt--;
            }
            l++;
        }
    }
    printf("%d\n",ans*10);
    return 0;
}

(4)第四题:摧毁

情况:赛中10分,已补题

题意:(1)使用定点激光武器花费 1 PW 的代价摧毁任意轨道上指定的一个卫星。
           (2)使用脉冲轨道武器花费 c PW 的代价把某一轨道上的所有卫星摧毁。

            求将这些卫星全部摧毁的最小代价是多少?

题解:用桶,如果定点激光武器花费的代价少,就用激光武器,如果脉冲轨道武器花费的代价少,就用脉冲轨道武器,最后输出激光武器花费的代价和脉冲轨道武器花费的代价。

赛后总结:赛中没看懂,赛后老师讲后就懂了。

AC代码:

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<vector>
using namespace std;
const int N=5e6+5;
int cnt[N],t;
int main(){
    cin>>t;
    while (t--){
        int n,c,x,ans=0;
        memset(cnt,0,sizeof cnt);
        cin>>n>>c;
        for (int i=1;i<=n;i++){
            cin>>x;
            cnt[x]++;
        }
        for(int i=1;i<=N;i++){
            ans+=min(c,cnt[i]);
        }
        cout<<ans<<endl;
    }
    return 0;
}

四.赛事总结

本次比赛中写freopen的时候,想了后久才想的起来,以后要背熟,仔细检查文件,写题时也要多思考,不能马上下定论,觉得自己不会写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值