Codeforces Round #702 (Div. 3)

A. Dense Array
题解:每次乘二即可。

#include<bits/stdc++.h>
using namespace std;
int a[60];
int main()
{
    int t, n, i;
    scanf("%d", &t);
    while (t--){
        scanf("%d", &n);
        for (i = 1; i <= n; i++)
            scanf("%d", &a[i]);
        int res = 0;
        for (i = 1; i < n; i++){
            int mi = min(a[i], a[i + 1]);
            int mx = max(a[i], a[i + 1]);
            while ((mx + mi - 1) / mi > 2)//向上取整
                mi *= 2, res++;
        }
        printf("%d\n", res);
    }
}

B. Balanced Remainders
题解:余数为0,1,2的相互转换。

#include<bits/stdc++.h>
using namespace std;
int a[30010];
int main()
{
    int t, n, i;
    scanf("%d", &t);
    while (t--){
        int c0 = 0, c1 = 0, c2 = 0;
        scanf("%d", &n);
        for (i = 1; i <= n; i++){
            scanf("%d", &a[i]);
            if (a[i] % 3 == 0) c0++;
            else if (a[i] % 3 == 1) c1++;
            else c2++;
        }
        int res = 0;
        while (c0 < n / 3){
            if (c1 > n / 3){
                res += 2;
                c1--;
                c0++;
            }
            else{
                res++;
                c2--;
                c0++;
            }
        }
        while (c1 < n / 3){
            if (c2 > n / 3){
                res += 2;
                c2--;
                c1++;
            }
            else{
                res++;
                c0--;
                c1++;
            }
        }
        while (c2 < n / 3){
            if (c0 > n / 3){
                res += 2;
                c0--;
                c2++;
            }
            else{
                res++;
                c1--;
                c2++;
            }
        }
        printf("%d\n", res);
    }
}

C. Sum of Cubes
题解:枚举a,二分查找b。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    long long x, i, j;
    scanf("%d", &t);
    while (t--){
        int flag = 0;
        scanf("%lld", &x);
        for (i = 1; i * i * i < x; i++){
            if (flag) break;
            long long l = 1, r = 1e4, mid;
            while (l <= r){
                mid = (l + r) / 2;
                if (i * i * i + mid * mid * mid == x){
                    flag = 1;
                    break;
                }
                else if (i * i * i + mid * mid * mid < x) l = mid + 1;
                else r = mid - 1;
            }
        }
        if (flag) printf("YES\n");
        else printf("NO\n");
    }
}

D. Permutation Transformation
题解:建树,以最大值作为根节点,再递归左子树和右子树。

#include<bits/stdc++.h>
using namespace std;
int a[110];
int d[110];
void build(int l, int r, int depth)
{
    if (l > r) return;
    int mx = 0, id;
    for (int i = l; i <= r; i++){
        if (a[i] > mx){
            mx = a[i];
            id = i;
        }
    }
    d[id] = depth;
    build(l, id - 1, depth + 1);
    build(id + 1, r, depth + 1);
}
int main()
{
    int t, n, i;
    scanf("%d", &t);
    while (t--){
        scanf("%d", &n);
        for (i = 1; i <= n; i++)
            scanf("%d", &a[i]);
        build(1, n, 0);
        for (i = 1; i <= n; i++){
            if (i > 1) printf(" ");
            printf("%d", d[i]);
        }
        printf("\n");
    }
}

E. Accidental Victory
题解:升序处理后,如果前i-1项的和>=第i项,那么第i-1项可以拿;如果小于就不能再拿了,因为前i-1项都小于那么前i-2、i-3项一定小于。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node
{
    ll num;
    int id;
}a[200010];
bool cmp(node e, node f)
{
    return e.num < f.num;
}
ll pre[200010];
int main()
{
    int t, n, i;
    scanf("%d", &t);
    while (t--){
        map<int, int>mp;
        scanf("%d", &n);
        for (i = 1; i <= n; i++){
            scanf("%lld", &a[i].num);
            a[i].id = i;
        }
        sort(a + 1, a + 1 + n, cmp);
        mp[a[n].id] = 1;
        for (i = 1; i <= n; i++)
            pre[i] = pre[i - 1] + a[i].num;
        int res = 1, p = 0;
        for (i = n - 1; i >= 1; i--){
            if (pre[i] >= a[i + 1].num){
                res++;
                mp[a[i].id] = 1;
            }
            else break;
        }
        printf("%d\n", res);
        for (i = 1; i <= n; i++){
            if (mp[i]){
                if (p) printf(" ");
                printf("%d", i);
                p++;
            }
        }
        printf("\n");
    }
}

F. Equalize the Array
题意:问最少删几个数使得剩余数的出现次数相同。
题解:枚举出现次数C。如果当前数的出现次数比C小的话,出现次数只能减少不能变多,所以得把这个数删掉;如果和C相同不作处理;如果比C大,那么次数减少到和C相同即可。

#include<bits/stdc++.h>
using namespace std;
int a[200010];
int b[200010];
int suf_b[200010];
int pre[200010];
int suf[200010];
int main()
{
    int t, n, i;
    scanf("%d", &t);
    while (t--){
        int mx = 0;
        map<int, int>mp1;
        map<int, int>mp2;
        memset(b, 0, sizeof(b));
        memset(pre, 0, sizeof(pre));
        memset(suf, 0, sizeof(suf));
        memset(suf_b, 0, sizeof(suf_b));
        scanf("%d", &n);
        for (i = 1; i <= n; i++){
            scanf("%d", &a[i]);
            mp1[a[i]]++;
            mx = max(mx, mp1[a[i]]);//Cmax
        }
        for (i = 1; i <= n; i++){
            if (!mp2[a[i]]){//mp2判断a[i]有无用过
                b[mp1[a[i]]]++;//统计某一次数的种类数
                mp2[a[i]] = 1;
            }
        }
        for (i = 1; i <= n; i++) pre[i] = pre[i - 1] + b[i] * i;//前i次的数字个数
        for (i = n; i >= 1; i--) suf[i] = suf[i + 1] + b[i] * i;//后i次的数字个数
        for (i = n; i >= 1; i--) suf_b[i] = suf_b[i + 1] + b[i];//后i次的种类数
        int mi = 1e9 + 10;
        for (i = 1; i <= mx; i++)
            mi = min(mi, pre[i - 1] + suf[i + 1] - suf_b[i + 1] * i);//出现i-1次以下的直接删掉,出现i次的不作处理,出现i+1次以上的减到i次为止
        printf("%d\n", mi);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值