Codeforces Round #765 (Div. 2) 题解(A-C)

本来想偷懒的,回头来还是写了。

A. Ancient Civilization

题意

给出含有n个数的数组,和数组中的数的二进制位大小。
定义距离d(x,y)为x和y不同二进制位的个数,输出一个数,使得这个数到数组中所有数的距离之和最小。

题解

因为是到数组中所有的数,考虑贪心。我们把每一位是1的出现次数统计出来,如果大于总数一半,输出值的这一位就置1,否则置0。

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <deque>
#include <iostream>
#include <map>
#include <deque>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#include <bitset>
#include <tuple>
#define ll long long
#define pi acos(-1)
#define hu(x) x*pi/180.0
#define mod 998244353
#define linf 0x7fffffffffffff
using namespace std;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    ll T;
    cin >> T;
    while (T--) {
        int n, l ,s;
        cin >> n >> l;
        int num[35];
        memset(num, 0, sizeof(num));
        for (int i = 0; i < n; i++) {
            cin >> s;
            bitset<35> bit(s);
            for (int j = 0; j < 34; j++) {
                if (bit[j] == 1) num[j]++;
            }
        }
        int re = 0;
        for (int i = 0; i < 34; i++) {
            if (num[i] > n / 2) re += (1 << i);
        }
        cout << re << endl;
    }
    return 0;
}

B. Elementary Particles

题意

给出含有n个数的数组,找出两个长度相同且起始点和终点不同的区间,使得这两个区间中的某个相同位数相同,求这个区间最大长度。

题解

我们发现,对于任意两个相同的数,最大区间长度=(左边的数的左边的数的个数+右边的数右边的数的个数+1)。
例如,对于
1 2 3 4 2 7 5 6
中的两个2,两个最长区间为1 2 3 4 2和4 2 7 5 6。长度又左边的2的左边的数的个数和右边的2右边的数的个数决定。
而使得这两个数的和尽可能大,易知两个数越近越好。
所有我们排序后遍历一遍即可。

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <deque>
#include <iostream>
#include <map>
#include <deque>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#include <bitset>
#include <tuple>
#define ll long long
#define pi acos(-1)
#define hu(x) x*pi/180.0
#define mod 998244353
#define linf 0x7fffffffffffff
using namespace std;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    ll T;
    cin >> T;
    while (T--) {
        int n;
        cin >> n;
        pair<int,int>* num = new pair<int, int>[n];
        for (int i = 0; i < n; i++) {
            cin >> num[i].first;
            num[i].second = i;
        }
        sort(num, num + n);
        int re = 0;
        int last = num[0].first;
        int lastw = num[0].second;
        for (int i = 1; i < n; i++) {
            if (num[i].first == last) {
                re = max(re, lastw + n - num[i].second);
            }
            last = num[i].first;
            lastw = num[i].second;
        }
        if (re == 0) cout << -1 << endl;
        else cout << re << endl;
    }
    return 0;
}

C. Road Optimization

给出一条从路,同时给出每一段限速的倒数和所在位置,我们可以去掉最多k个限速,求最少的时间。

题解

参考了tourist的做法。
考虑dp,我们用dp[i][j]表示从i开始去掉i前面不大于k个限速的时间,p每循环一次就列出所有拆除j个的情况,状态转移方程为dp[i][j] = min(dp[i][j], dp[p][old] + (a[i] – a[p]) * b[p])。然后我们可以在dp[n]中找出拆除从0-k个的最小时间。

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <deque>
#include <iostream>
#include <map>
#include <deque>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#include <bitset>
#include <tuple>
#define ll long long
#define pi acos(-1)
#define hu(x) x*pi/180.0
#define mod 998244353
#define linf 0x7fffffffffffff
#define inf 0x7f7f7f7f
using namespace std;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, l, k;
    cin >> n >> l >> k;
    int* a = new int[n+1];
    int* b = new int[n+1];
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for (int i = 0; i < n; i++) {
        cin >> b[i];
    }
    a[n] = l;
    b[n] = 0;
    ll dp[505][505];
    memset(dp, 0x7f, sizeof(dp));
    dp[0][0] = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= k; j++) {
            for (int p = i - 1; p >= 0; p--) {
                int old = j - (i - p - 1);
                if (old >= 0) {
                    dp[i][j] = min(dp[i][j], dp[p][old] + (a[i] - a[p]) * b[p]);
                }
            }
        }
    }
    cout << *min_element(dp[n], dp[n] + k + 1) << endl;
    return 0;
}
知识共享许可协议
Text is available under CC BY-NC-SA 4.0 unless otherwise stated.

除非特殊声明,本站所有内容均以 CC BY-NC-SA 4.0协议授权。
上一篇
下一篇