Educational Codeforces Round 103 (Rated for Div. 2)A. K-divisible Sum B. Inflation C. Longest Simple

A. K-divisible Sum

数学

题意:选n个正整数,使得和能够整除K,并且这n个整数中的最大数尽可能的小。最大尽可能小,所以要求最小和,再让最小和给n个数均摊,找到其中最大的值。

当n<=k, 最小和就是K,n个数中的最大的数就是k/n向上取整,
向上取整方法:(n+k-1)/k;

当n>k,最小和就是n/k向上取整再*K,然后n个数的最大数就是最小和向除n上取整

其实不管n和K的关系最小和就是n/k向上取整再*K

AC代码

#include <iostream>
using namespace std;
int main(){
    
    
    long long n,k,sum,ans;
    int T;
    cin >> T;
    for(int i = 0;i < T;i++){
    
    
        cin >> n >> k;
        sum =(n + k -1)/k * k;
        ans = (sum + n -1)/n;
        cout << ans << endl;
    }
    //system("pause");
    return 0;
}

B. Inflation

思维

题意: 给你n个数字,n个数字和k,第一个数字是商品起始价格,之后是每个月涨了多少。>要求每个人月涨价前/涨价后 <= k/100.

涨价前/涨价后 <= k/100. 涨价前100 <= k涨价后 能用乘法就不要用除法。避免精度丢失问题。

每个月都要满足上式,所以如果不满足,只能上调价格!!!,求最少总共了改变多少价格。所以一旦不满足上式,你只要上调涨价前的价格直到刚好满足上式就好,不许要像下面的Note那样,(感觉就是在误导)

Note
In the first test case, you can, for example, increase p0 by 50 and p1 by 49 and get array [20150,50,202,202]. Then you get the next inflation coefficients:

AC代码

#include <iostream>
using namespace std;
int main(){
    
    
    int T,n;
    int k;
    cin >>T;
    long long sum,x,ans,sum1;
    for(int t = 0;t < T;t++){
    
    
        cin >> n >> k;
        ans = 0;
        cin >> sum;
        for(int i = 1;i < n;i++){
    
    
            cin >> x;
           
            if(x*100 > sum *k){
    
    
                //cout << x << " x" << endl;
                sum1 = (100*x + k -1)/k;
                
                ans+=(sum1-sum);
                sum = sum1;
                
            }
             sum +=x;
        }
        cout << ans << endl;
    }
    //system("pause");
    return 0;
}

C. Longest Simple Cycle

贪心

题意:让你从n个连接的链条中找长度最长的简单环(绕环一圈只过每个点一次)因此 ai > bi也满足,也就是有边交叉也是满足的,所以每次加上ai——bi的长度是abs(ai-bi),但ai == bi时,i 和i -2个链条就不能相连了

贪心,对于第i条,如果能和第i-2条相连(ai!=bi)那么就判断连和不连哪个长,然后选择长的个保存为 当前对于下个链条有作用的最大环,对于第i条链子.画图不难发现如果第i-2条不连(不经过i-2上面的点)更大,那么第i-2条对之后也没有帮助,所以可以放心丢弃,也就是无后效性所以可以贪心。然后再和已有的最大值比较就行。

在这里插入图片描述

AC代码

#include <iostream>
#include <stdlib.h>
using namespace std;
int num[100200];
int a[100020];
int b[100020];
long long max(long long a,long long b){
    
    
    return a > b?a:b;
}
int main(){
    
    
    int T;
    int n;
    long long ans,sum,x,x1;
    cin >> T;
    for(int t  = 0;t < T;t++){
    
    
        scanf("%d",&n);
        ans = 0;
        sum = 0;
        for(int i = 0;i < n;i++)
            scanf("%d", &num[i]);
        for(int i = 0;i < n;i++)
            scanf("%d",&a[i]);
        for(int i = 0;i < n;i++)
            scanf("%d",&b[i]);
        ans = 0;
        for(int i = 1;i < n;i++){
    
    
            if(a[i] == b[i])
                sum = 0;//前面的连不起来 如果sum是max就已经被收了就没有意义了
            x = num[i]+1 + abs(a[i]-b[i]);//只取第i个
            x1 = sum;//在前面的基础上取第i个
            if(x1)  
                x1-=abs(a[i]-b[i]);

            x1+=(1+num[i]);

            sum = max(x,x1);//取了第i个的最大环 如果只取i 比取i和之前相连,就说明i之前的没有意义,
            //可以扔了
            ans = max(ans,sum); 

        }
        printf("%lld\n",ans);
    }
    //system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/RunningBeef/article/details/113462077