2020.4.18-BNUZ

文章目录

    • [A - Greed](https://vjudge.net/contest/368840#problem/A)
    • [B - Wrath](https://vjudge.net/contest/368840#problem/B)
    • [C - Pride](https://vjudge.net/contest/368840#problem/C)
    • [D - Splitting in Teams](https://vjudge.net/contest/368840#problem/D)

A - Greed

题意
判断能否将可乐倒入两个罐子
题解
计算可乐体积和,判断最大容量的两个罐子是容量和是否比可乐体积大,注意取值范围到10^9,求和可能超过int范围。
代码

#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
     
    long long int a[100005],b[100005];
    long long int sum = 0;
    int n;
    while(~scanf("%d",&n)){
     
        sum = 0;
        for(int i = 0;i < n;i++){
     
            scanf("%lld",&a[i]);
            sum += a[i];
        }
        for(int i = 0;i < n;i++){
     
            scanf("%lld",&b[i]);
        }
        sort(b, b+n);
        if(sum <= b[n-1]+b[n-2])
            printf("YES\n");
        else
            printf("NO\n");
    }
    
}

B - Wrath

题意
每个人有一定长度的利爪,可以杀掉距离他前面爪长度内的人,求最后剩下的人
代码

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
int main(){
     
    //a储存每个人的利爪,b储存当前能杀到的人的位置
    int a[1000005],b[1000005];
    int n;
    while(~scanf("%d",&n)){
     
        for(int i = 1;i <= n;i++){
     
            scanf("%d",&a[i]);
            b[i] = n;
        }
        //最后一个人不会死
        int num = 1;
        //最后一个人能杀到的位置
        b[n] = n-a[n];
        //倒着遍历就不会漏掉
        for(int i = n-1;i > 0;i--){
     
            //如果当前的人能杀到的人位置小于上一个人杀到的位置就记录当前的最小位置
            b[i] = i-a[i] < b[i+1]?i-a[i]:b[i+1];
            //如果当前这个人的位置小于上一个人能杀到的范围说明他能活着
            if(i < b[i+1])
                num++;
        }
        printf("%d\n",num);
    }

}

C - Pride

题意
一组数组可以将两个相邻的数其中一个用最大公约数替换,求将 所有数变成1的最少变换次数
代码

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
//最小公约数-辗转相除法
int gcd(int x,int y){
     
    int c = x%y;
    if(c == 0)
        return y;
    c = gcd(y, c);
    return c;
}
int main(){
     
    int a[2005];
    int n;
    while(~scanf("%d",&n)){
     
        int count = 0;
        for(int i = 1;i <= n;i++){
     
            scanf("%d",&a[i]);
            //记录1的个数
            if(a[i] == 1){
     
                count++;
            }
        }
        //如果有1,输出结果一定是n-count
        if(count){
     
            printf("%d\n",n-count);
            return 0;
        }
        //如果没有1
        int Min = 2000;
        int m = 0,flag = 0;
        //遍历枚举最小的变换次数
        for(int i = 1;i <= n-1;i++){
     
            int ans = 0;
            //m是两个相邻的数的最小公约数,相当于两个相邻的数是替换的第二个数
            m = a[i];
            for(int j = i+1;j <= n;j++){
     
                ans++;
                m = gcd(a[j], m);
                if(m == 1){
     
                    flag = 1;
                    break;
                }
            }
            if(m == 1)
                Min = min(Min,ans);
        }
        if(!flag)
            printf("-1\n");
        else
            printf("%d\n",n+Min-1);
    }
    return 0;
}

D - Splitting in Teams

题意
三人组成一组,原本是两个人一组的不能拆散,求最多能组几组
代码

#include <stdio.h>
#include <string.h>
int main(){
     
    int a[200010];
    int n;
    scanf("%d",&n);
    int c1 = 0,c2 = 0;
    for(int i = 0;i < n;i++){
     
        scanf("%d",&a[i]);
        if(a[i] == 1)
            c1++;
        else
            c2++;
    }
    int sum = 0;
    if(c2 <= c1){
     
        sum += (c2 + (c1-c2)/3);
    }
    else
        sum += c1;
    printf("%d\n",sum);
}

你可能感兴趣的:(2020.4.18-BNUZ)