Educational Codeforces Round 66 Rated for Div. 2(部分题目)

Educational Codeforces Round 66 Rated for Div. 2

A. From Hero to Zero

题意:
给定一个n和一个k,通过以下操作将n转换为0

  1. n=n-1
  2. 若n可以整除k,n = n/2

输出从n转换到0所需要的 最小次数

思路:
除k的情况时贡献度最高的,要优先考虑除k。
通过直接减去当前n对k的余数,节省减一操作的时间。

代码简化:
利用整形变量抹去小数点的性质,每次操作增加当前n对k的余数加1后,n更新为n除k。最后对于答案减去多余的一次除操作。

#include<bits/stdc++.h>
using namespace std;

int main(){
    int t;
    cin>>t;
    while(t--){
        long long n,k;
        cin>>n>>k;
        long long ans=0;
        while(n){
            long long a=n%k;
            n/=k;
            ans+=a+1;
        }
        cout<<ans-1<<endl;
    }
    return 0;
}

B. Catch Overflow!

题意:
给出以下模式的伪代码,模拟循环累加操作。

  1. for n(1≤n≤100)——表示进行n次循环
  2. end——表示循环体结束
  3. add——表示进行一次累加

给出的伪代码中,add能出现在循环体内外,for之后可以马上接end(无循环体),保证for 和end 都能对应上。

若最后答案没有超过 2 32 − 1 2 ^ {32} -1 2321,输出准确的累加答案;否则,输出“OVERFLOW!!!”

思路:
模拟,利用栈对于循环次数的累乘进行统计,利用两个标记来对整个模拟进行控制。
一旦累计循环次数比 2 32 − 1 2 ^ {32} -1 2321大则做出标记Ⅰ。
当标记Ⅰ存在时,循环累乘结果不再需要记录实际值,若出现add,则做出标记Ⅱ。
出现end时,弹出栈顶并统计累加结果;若存在标记Ⅱ,则不需要进一步计算。

最后根据标记Ⅱ的有无,决定输出的种类

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAx  = 4294967296;
stack<ll>s;
int main()
{
    int n;
    s.push(1);
    while(cin>>n)
    {

        ll f=1;
        ll ans=0;
        ll flag1=0;
        bool flag=0;
        while(n--)
        {

            char c[4];
            cin>>c;
            if(c[0]=='a')
            {
                if(ans+s.top()>=MAx||flag1>0)
                    {flag=1;continue;}
                ans+=s.top();
            }
            if(c[0]=='f')
            {
                ll a;
                cin>>a;
                if(s.top()>=MAx||a*s.top()>=MAx){flag1++;s.push(MAx);}//使用标记Ⅰ记录超额累乘for的个数
                else s.push(a*s.top());
            }
            if(c[0]=='e')
            {
                if(flag1!=0)flag1--;
                s.pop();

            }
        }
        if(flag)
            cout<<"OVERFLOW!!!"<<endl;
        else
            cout<<ans<<endl;
    }
    return 0;
}

C. Electrification

题意:
给出数轴上的n个点a1~an,存在一个点x到ai的距离为di
将得到的n个di进行升序排序,得到一个第k大的距离dk+1

输出在dk+1尽量小的情况下,x的坐标

思路:
初始的dk+1表示的是x到ak+1的距离,但在排序后dk+1则是第k大的距离,二者是不一样的。所以我们需要构造出第k大的距离,换而言之,存在k-1个距离比它小或等于,存在n-k个距离比它大或等于。

我们假设点x为点ai到ai+k这段线段的中点,则在点ai到ai+k存在的k-1个点到x的距离,都会比ai到x小;反之,在两点之外的n-k-1的距离就会比它大,加上ai+k到x的距离就存在n-k个距离的条件。

所以ai到x的距离为所求的dk+1。此时,我们只限于找到ai到ai+k最短的一根线段,并求出中点(中位数)即可。

#include<bits/stdc++.h>
using namespace std;
int main(){
    int T;
    cin>>T;
    while(T--){
        int n,k;
        cin>>n>>k;
        long long a[200005];
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        long long MIN=a[k]-a[0];
        long long l=0,r=k;
        for(int i=1;(i+k)<n;i++){
            if(a[i+k]-a[i]<MIN){
                MIN=a[i+k]-a[i];
                l=i;r=i+k;
            }
        }
        cout<<(a[r]+a[l]+1)/2<<endl;
    }
    return 0;				
}

D. Array Splitting

题意:
给出一个数组,要求将这个数组分成k组,每组产生一个cost。
假设第i组的求和是Si ,它的cost就是 S &lt; s u b &gt; i &lt; / s u b &gt; ∗ i S&lt;sub&gt;i&lt;/sub&gt;*i S<sub>i</sub>i

输出k组cost求和最大的情况。

思路:
题目要求构造出 ∑ S &lt; s u b &gt; i &lt; / s u b &gt; ∗ i ∑S&lt;sub&gt;i&lt;/sub&gt;*i S<sub>i</sub>i最大值。与其从头开始判断每一组怎么去才能最大,不如直接求出 ∑ S &lt; s u b &gt; i &lt; / s u b &gt; ∗ k ∑S&lt;sub&gt;i&lt;/sub&gt;*k S<sub>i</sub>k再减去k-1个前缀和。
只要每次都贪心减去当前最小的前缀和,就能的到所求

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[1000005];
ll s[1000005]={0};
int main()
{
    int n,k;
    while(cin>>n>>k){

        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        s[0]=a[0];
        for(int i=1;i<n;i++){
            s[i]=a[i]+s[i-1];
        }
        s[n-1]*=k;
        sort(s,s+n-1);
        for(int i=0;i<k-1;i++){
            s[n-1]-=s[i];
        }
        cout<<s[n-1]<<endl;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值