CSP-X模拟赛四补题报告

 Coduck S14754        赵廷赫

一,比赛概况

T1,3,4  0分 T240分。

二,补题报告

T1:

小可的除法练习(exdiv)

时间限制:1秒        内存限制:128M

题目描述

小可学习了除法!然后达达为了难住小可,出了这么一个问题:

有n、n个整数a_1,a_2,\cdots ,a_na​1​​,a​2​​,⋯,a​n​​,需要找到一个绝对值最小的非00整数xx,满足\frac{a_i}{x} > 0​x​​a​i​​​​>0的a_ia​i​​的数量大于等于\frac{n}{2}​2​​n​​向下取整。

如果存在绝对值相等的两个数都满足条件且绝对值最小, 输出正数。

如果不存在这样的数,输出00。

小可被难住啦!快来帮帮小可。

输入描述

第一行一个整数n,代表数字的数量。
第二行n个整数a​i​​

输出描述

如题,输出满足条件的x

样例输入

70 0 1 -1 0 0 2

样例输出

0

数据范围

对于20的数据,n≤100

对于60%的数据,n<=10^5

对于100%的数据,ai<=≤10^​12​​,1≤n≤10^​6

题目解析:

是不是感觉很难?

确实不好理解。

通过亿点点小小的分析,可以看出:

1,输出的答案和ai的值没有关系

2,输出只有3种情况:0,-1,1。

3,如果负数比正数多,答案是-1。

4,如果正数,负数都没过n/2,输出0。

5,否则,正数数量>=复数,输出1。

这样是不是有手就行了?

注意用scanf和printf。

好,废话不多说,不多说废话,上AC代码:

#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
    int n,m,z=0,f=0,t;
    scanf("%d",&n);
    m=n/2;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&t);
        if(t>0)
        {
            z++;
        }
        else if(t<0)
        {
            f++;
        }
    }
    if(f>m) 
    {
        cout<<-1;
    }
    else if(f<m&&z<m)
    {
        cout<<0;
    }
    else
    {
        cout<<1;
    }
    return 0;
}

T2:

小可买糖豆(jelly)

时间限制:1秒        内存限制:128M

题目描述

小可想要买好多好多糖豆!并且要用小可喜欢的小罐罐装!

只有装满了一个罐罐,小可才会用下一个罐罐。

小可进行了n次购买操作,每次购买操作结束之后,请你告诉小可,这次购买操作装满了多少个罐罐!

输入描述

第一行两个正整数n,m,代表小可进行了n次购买操作,以及每个小罐罐最多能装多少个糖豆。

第二行n个整数a​1​​,a​2​​,⋯,a​n​​,代表小可这一次买了多少个糖豆。

输出描述

对于每次购买操作,都要输出有多少个小罐罐在这一次购买操作中被装满了。

样例输入

4 52 2 1 5

样例输出

0 0 1 1

数据范围

对于40%的数据,n≤1000

对于100%的数据,1<=ai,m<=10^9,1<=n<=10^5.

题目解析:

没啥好说,直接模拟。

依然要用scanf和printf。

上AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
using namespace std;
int main()
{
    long long n,m,sum=0,x;
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&x);
        printf("%lld",(sum+x)/m);
        sum=(sum+x)%m;
    }
    return 0;
}

T3:

序列分块(piecemeal)

时间限制:1秒        内存限制:128M

题目描述

小可手中有一个序列a,小可可以在序列a中选定一个区间[l,r][l,r],然后将这个区间分成单独的一块,其他不在块内的数字全部忽略不计。显然小可有许多分块方案。分块之后,小可还需要对这个分块计算出一个评分:

评分的计算规则如下:对于分块的这个区间[l,r][l,r],小可把这个区间划分成cc个连续的小段,每段为 [l_1,r_1],[l_2,r_2],\cdots,[l_c,r_c][l​1​​,r​1​​],[l​2​​,r​2​​],⋯,[l​c​​,r​c​​],并且这个区间中的每个数都属于其中一个小段,不存在一个数被多个小段包含的情况。这时候的评分为:

c+\sum_{i=1}^c MEX(a[l_i],a[l_i+1],\cdots,a[r_i])c+∑​i=1​c​​MEX(a[l​i​​],a[l​i​​+1],⋯,a[r​i​​])

其中 MEX(S)MEX(S) 为最小的没有出现在集合 SS 中的非负整数。换句话说,如上评分的值为划分的段数加上每一段的 MEXMEX 值。

小可想知道,所有的分块方案的最大评分的和是多少。

输入描述

第一行一个正整数t1≤t≤30),代表有t组输入。

对于每组输入,第一行一个整数n(1≤n≤100),代表序列a的长度。
第二行n个整数(0≤a​i​​≤10​9​​),代表序列a中的每个数字。

保证这t组输入的n的总和不会超过100。

输出描述

对于每组输入,输出一行一个整数,代表所有的分块方案的最大评分的和。

样例输入

4
2
1 2
3
2 0 1
4
2 0 5 1
5
0 1 1 0 1

样例输出

4
14
26
48

提示

对于第二组输入,

分块 [2, 0, 1][2,0,1] 的最佳划分: [2], [0, 1][2],[0,1] 。 评分为 2 + mex({2}) + mex({0, 1}) = 2 + 0 + 2 = 42+mex(2)+mex(0,1)=2+0+2=4 。
分块 [2, 0][2,0] 的最佳划分: [2], [0][2],[0] 。评分为 2 + mex({2}) + mex({0}) = 2 + 0 + 1 = 32+mex(2)+mex(0)=2+0+1=3。
分块 [2][2]的最佳划分 : [2][2] 。 评分为 1 + mex({2}) = 1 + 0 = 11+mex(2)=1+0=1 。
分块 [0, 1][0,1] 的最佳划分: [0, 1][0,1] 。 评分为 1 + mex({0, 1}) = 1 + 2 = 31+mex(0,1)=1+2=3 。
分块 [0][0] 的最佳划分: [0][0] 。 评分为 1 + mex({0}) = 1 + 1 = 21+mex(0)=1+1=2 。
分块 [1][1] 的最佳划分: [1][1] 。 评分为 1 + mex({1}) = 1 + 0 = 11+mex(1)=1+0=1 。

所有分块方案的最大评分和为 4 + 3 + 1 + 3 + 2 + 1 = 144+3+1+3+2+1=14 。

对于4040%的数据,t=1,n<=10n<=10

对于100100%的数据,1<=t<= 30,1\<=n<=100 

AC代码:

#include<bits/stdc++.h>
using namespace std;
int a[105];
int main()
{
    int n,t,ans;
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
        }
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=i;j<=n;j++)
            { 
                for(int k=i;k<=j;k++)
                {
                    ans++;
                    if(a[k]==0)
                    {
                        ans++;
                    }
                }
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

T4:

射箭比赛(archery)

时间限制:1秒        内存限制:128M

题目描述

小可参加了一个射箭比赛。这个比赛有n个靶子,第i个靶子的位置为x​i​​。小可最开始的位置为0。

小可可以做如下操作,可以认为靶子被射中之后会消失:

  • 选择一个已经射中的靶子,小可的位置可以移动到这个靶子的位置上。假设小可和这个靶子的距离为c,那么这次移动需要消耗的体力为a×c。

  • 选择一个没有被射中的靶子,同时小可和这个靶子之间不能有其他未被射中的靶子。小可一定会射中。假设小可和这个靶子的距离为c,这个操作消耗的体力为b×c。

为了节省体力,小可想知道射完所有的靶子,所消耗的体力总和最小是多少。

输入描述

第一行一个正整数t(1≤t≤10​3​​),代表有t组输入。

对于每组输入,第一行三个正整数n,a,b (1≤n≤2×10​5​​,1≤a,b≤10​5​​)。
第二行n个整数x​1​​,x​2​​,⋯,x​n​​(1≤x​i​​≤10​8​​),代表每个靶子的位置。保证靶子的位置是单调递增的。

输出描述

对于每组输入,如题,输出答案。

样例输入

4
5 2 7
3 5 12 13 21
5 6 3
1 5 6 21 30
2 9 3
10 15
11 27182 31415
16 18 33 98 874 989 4848 20458 34365 38117 72030

样例输出

173
171
75
3298918744

提示

对于20%的数据,t=1,1≤n≤10。
对于60%的数据,1≤t≤10,1≤n≤100。
对于100%的数据。1≤t≤10​^3​​,1≤n≤2×10​^5​​,保证t组输入的n的和不会超过2*10^5。

AC代码:

#include<bits/stdc++.h>
using namespace std;
long long a[200005],sum[200005];
int main()
{
    int t,n,ta,tb,c;
    cin>>t;
    while(t--)
    {
        cin>>n>>ta>>tb;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            sum[i]=sum[i-1]+a[i];
        }
        long long pos=0,ans=0;
        for(int i=1;i<=n;i++)
        {
            ans+=(a[i]-pos)*tb;
            long long ans1=(sum[n]-sum[i]-(n-i)*pos)*tb;
            long long ans2=(a[i]-pos)*ta+(sum[n]-sum[i]-a[i]*(n-i))*tb;
            if(ans2<ans1)
            {
                ans+=(a[i]-pos)*ta;
                pos=a[i];
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值