Codeforces Round #702 (Div. 3)

Codeforces Round #702 (Div. 3)

A. Dense Array

题意:

题解:

代码:

#include <bits/stdc++.h>

#define int long long
using namespace std;

inline int read() {
    int s = 0, w = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-') w = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
    return s * w;
}

int const MAXN = 2e5 + 10;
int n, m, T;
int a[MAXN];
map<int, int> mp;
void init() {
    mp[1] = 0;
    mp[2] = 0;
    mp[4] = 1;
    mp[8] = 2;
    mp[16] = 3;
    mp[32] = 4;
    mp[64] = 5;
}
signed main() {
    cin >> T;
    init();
    while (T--) {
        cin >> n;
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
        }
        int ans = 0;
        for (int i = 2; i <= n; i++) {
            int k = (int)ceil(1.0*max(a[i - 1], a[i]) / min(a[i - 1], a[i]));
            for (auto it = mp.begin(); it != mp.end(); it++) {
                if (k <= it->first) {
                    ans += it->second;
                    //cout << i << "->" << it->second << endl;
                    break;
                }
            }
        }
        //cout << "ans:";
        cout << ans << endl;
    }
    return 0;
}

B. Balanced Remainders

题意: 给定n个数字,每个数字%3,每次可以把%完为i得数字减一,%完为i+1得数字加一,问最少操作多少次,能够使得%完为0、1、2的数字数目相同。

题解: 暴力。每次将最多的减一,不断操作,直到所有的数目相同。

代码:

#include <algorithm>
#include <cstdio>
#include <iostream>
using namespace std;
const int N = 3e4 + 10;

int T;
int n;
int a[N];

signed main() {
    cin >> T;

    while (T--) {
        scanf("%d", &n);

        int c0 = 0, c1 = 0, c2 = 0;
        for (int i = 0; i < n; i++) {
            scanf("%d", &a[i]);
            if (a[i] % 3 == 0)
                c0++;  //统计余数个数
            else if (a[i] % 3 == 1)
                c1++;
            else if (a[i] % 3 == 2)
                c2++;
        }

        int res = 0;  //操作次数
        while (c0 != c1 || c0 != c2 || c1 != c2) {
            res++;
            if (c0 >= c1 && c0 >= c2)
                c0--, c1++;
            else if (c1 >= c0 && c1 >= c2)
                c1--, c2++;
            else if (c2 >= c0 && c2 >= c1)
                c2--, c0++;
        }

        printf("%d\n", res);
    }
}

C. Sum of Cubes

题意:

题解:

代码:

#include <bits/stdc++.h>

#define int long long
using namespace std;

inline int read() {
    int s = 0, w = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-') w = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
    return s * w;
}

int const MAXN = 1e12;
int n, m, T;
set<int> st;

void init() {
    for (int i = 1; i * i * i <= MAXN; i++) {
        st.insert(i * i * i);
    }
}

signed main() {
    T = read();
    init();
    while (T--) {
        int x = read();
        bool f = 0;
        for (auto it = st.begin(); it != st.end(); it++) {
            int a = *(it);
            int b = x - a;
            if (st.count(b)) {
                cout << "YES" << endl;
                f = 1;
                break;
            }
        }
        if (!f) cout << "NO" << endl;
    }
    return 0;
}

D. Permutation Transformation

题意:

题解: 纯暴力。

代码:

#include <bits/stdc++.h>

#define int long long
using namespace std;

inline int read() {
   int s = 0, w = 1;
   char ch = getchar();
   while (ch < '0' || ch > '9') {if (ch == '-') w = -1; ch = getchar();}
   while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
   return s * w;
}

int const MAXN = 110;
int n, m, T, a[MAXN], dep[MAXN];

void dfs(int l, int r, int val) {
    if (l > r) return;
    int Max_val = a[l], Max_pos = l;
    for (int i = l ; i <= r; ++i) {
        if (a[i] > Max_val) {
            Max_val = a[i];
            Max_pos = i;
        }
    }
    dep[Max_pos] = val;
    dfs(l, Max_pos - 1, val + 1);
    dfs(Max_pos + 1, r, val + 1);
}

signed main() {
    T = read();
    while(T--) {
        n = read();
        for (int i = 1; i <= n; ++i) a[i] = read(), dep[i] = 0;
        dfs(1, n, 0);
        for (int i = 1; i <= n; ++i) printf("%d ", dep[i]);
        puts("");
    }
    return 0;
}

E. Accidental Victory

题意:

题解:

代码:

#include <bits/stdc++.h>

#define int long long
using namespace std;

inline int read() {
    int s = 0, w = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-') w = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
    return s * w;
}

int const MAXN = 3e5 + 10;
int n, m, T;
pair<int,int> a[MAXN];
int sum[MAXN];
int b[MAXN];
signed main() {
    cin >> T;
    while (T--) {
        cin >> n;
        for (int i = 1; i <= n; i++) {
            cin >> a[i].first;
            a[i].second = i;
        }
        int ans = 1;
        sort(a + 1, a + 1 + n);
        for (int i = 1; i <= n; i++) {
            sum[i] = a[i].first + sum[i - 1];
            if (a[i].first > sum[i - 1]) ans = i;
        }
        cout << n - ans + 1 << endl;
        int cnt = 0;
        for (int i = ans; i <= n; i++) {
            b[cnt++]= a[i].second;
        }
        sort(b, b + cnt);
        for (int i = 0; i < cnt; i++) {
            cout << b[i] << " ";
        }
        cout << endl;
    }
    return 0;
}

F. Equalize the Array

题意: 问最小删除多少个数字使得剩下的数字出现次数都一样。

题解: 计数出现次数为1、2…n的个数,然后倒着维护即可。

代码:

#include <bits/stdc++.h>

#define int long long
using namespace std;

inline int read() {
    int s = 0, w = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-') w = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
    return s * w;
}

int const MAXN = 2e5 + 10;
int n, m, T;
map<int, int> mp;
int num[MAXN], sum[MAXN];
signed main() {
    T = read();
    while (T--) {
        n = read();
        mp.clear();
        memset(num, 0, sizeof num);
        for (int i = 1; i <= n; i++) {
            int x;
            x = read();
            mp[x]++;
        }
        int max_num = 0;
        for (auto it = mp.begin(); it != mp.end(); it++) {
            num[it->second]++;
            max_num = max(max_num, it->second);
        }
        for (int i = 1; i <= max_num; i++) {
            // cout << i<<":"<<num[i] << endl;
            sum[i] = sum[i - 1] + num[i] * i;
        }
        int ans = 0x3f3f3f3f3f3f3f3f;
        int cnt = 0;
        int last = 0;
        // cout << max_num << endl;
        for (int i = max_num; i >= 1; i--) {
            last += cnt;
            if (!num[i]) continue;
            ans = min(ans, sum[i - 1] + last);
            cnt += num[i];
        }
        // cout << "ans:";
        if (ans == 0x3f3f3f3f3f3f3f3f)
            cout << 0 << endl;
        else
            cout << ans << endl;
    }
    return 0;
}

G. Old Floppy Drive

题意: 给定一个包含n 个整数的数组 a {a} a,可以循环延申至无穷个元素(定义编号 n n n的后一个元素为编号 1 1 1

再给定m 个询问x ,对于每个x

问无穷数组{ a } 的前缀和数组{ S } 中,第一次出现S i ≥ x 的下标i是多少(输出时下标要− 1 )

若不存在,输出− 1

题解: 题解看这个博主:https://blog.csdn.net/qq_36394234/article/details/113830619

代码:

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

int n, m;
LL Max[200050];

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int T;
    cin >> T;
    while (T--) {
        cin >> n >> m;

        LL s = 0;
        for (int i = 1; i <= n; i++) {
            LL d;
            cin >> d;
            s += d;
            Max[i] = max(Max[i - 1], s);
        }

        while (m--) {
            LL q;
            cin >> q;
            if (Max[n] >= q)
                cout << (lower_bound(Max + 1, Max + 1 + n, q) - Max) - 1 << ' ';
            else {
                if (s <= 0)
                    cout << "-1 ";
                else {
                    LL d = q - Max[n];
                    LL tim = (d + s - 1) / s;
                    q -= tim * s;
                    cout << (lower_bound(Max + 1, Max + 1 + n, q) - Max + tim * n) - 1
                        << ' ';
                }
            }
        }
        cout << '\n';
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值