欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

Codeforces Global Round 15 ABCD

发布时间:2023/12/14 30 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Codeforces Global Round 15 ABCD 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

A. Subsequence Permutation

题意:

给定一个字符串,选择任意数量的字符调整位置,使得调整位置之后整个序列是从小到大的,要求调整的位置数量最小

输入

4
3
lol
10
codeforces
5
aaaaa
4
dcba

输出

2
6
0
4

思路

这个没什么好说的,定义一个字符串,从小到大排序之后判断是不是和原位置的字符相等就可,另外注意不要用之前的位置和当前的位置比较

代码

#include <iostream> #include <algorithm> #include <cstring> #include <vector> #include <cmath> #include <stack> #include <queue> #include <set> #include <map>using namespace std;typedef long long ll; #define SSS \ios_base::sync_with_stdio(0); \cin.tie(0); \cout.tie(0);#define rep(i, a, b) for (int i = (a), i <= (b); i++) #define per(i, a, b) for (int i = (a), i >= (b); i--) #define pii pair<int, int> #define pdd pair<double, double> const int N = 1e5 + 10; const int mod = 1e9 + 7;int main() {SSS;int t;cin >> t;while (t--){int n;string s;cin >> n;cin >> s;string s1 = s;int cnt = 0;sort(s1.begin(), s1.end());for (int i = 0; i < s.size(); i++){if (s[i] != s1[i]){cnt++;}}cout << cnt << endl;}return 0; }

B - Running for Gold

题意:

有n个选手要参加马拉松比赛,并且每个马拉松选手以前都参加过5场比赛,如果存在一个选手,在任意三场比赛中都比另一个选手的成绩好,那么这个选手就强,如果有选手比其他所有的选手都强,那么就认为这个选手可以在本次马拉松比赛中拿第一,求是否存在这样的选手,存在输出这个选手的下标,否则输出-1

输入

4
1
50000 1 50000 50000 50000
3
10 10 20 30 30
20 20 30 10 10
30 30 10 20 20
3
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
6
9 5 3 7 1
7 4 1 6 8
5 6 7 3 2
6 7 8 8 6
4 2 2 4 5
8 3 6 9 4

输出

1
-1
1
5

思路

这题n<=50000, t<=1000,所以得想一个O(n)的做法,可以转换成打擂台的题,假设有选手A和B,A如果在任意三场比赛中强于B,那么B就必不可能是第一,那么我们可以按照这样模拟一个擂台,首先A上场,和B打,A或者B赢了的留下,作为当前的最强者继续和C打,那么到最后必定有一个人留下,这个人前面的必定都是被打下去的,这个人之后的都是被他打过的,然后对于这样的一个最强者,我们对他之前的选手进行遍历,寻找是否有比他强的,因为前面的人是被别人打下的,他自己不一定可以打下,如果存在这样的选手,就说明不存在可以拿第一的,否则输出当前选手下标

代码

#include <iostream> #include <algorithm> #include <cstring> #include <vector> #include <cmath> #include <stack> #include <queue> #include <set> #include <map>using namespace std;typedef long long ll; #define SSS \ios_base::sync_with_stdio(0); \cin.tie(0); \cout.tie(0); #define rep(i, a, b) for (int i = (a), i <= (b); i++) #define per(i, a, b) for (int i = (a), i >= (b); i--) #define pii pair<int, int> #define pdd pair<double, double> const int N = 5e4 + 10; const int mod = 1e9 + 7;int r[10][N]; int main() {SSS;int t;cin >> t;while (t--){int n;cin >> n;for (int i = 1; i <= n; i++){for (int j = 1; j <= 5; j++){cin >> r[j][i];}}int ans = 1; // 当前的最强者for (int i = 2; i <= n; i++){int cnt = 0;for (int j = 1; j <= 5; j++){if (r[j][ans] > r[j][i]){cnt++;}} // 如果有选手三项比赛的成绩大于当前的最强者就更新if (cnt >= 3){ans = i;}}int flag = 1; // 之后在遍历一遍,强者鉴定for (int i = 1; i <= n; i++){int cnt = 0;for (int j = 1; j <= 5; j++){if (r[j][ans] > r[j][i]){cnt++;}if (cnt >= 3){flag = 0;break;}}}if (flag){cout << ans << endl;}else{cout << -1 << endl;}}return 0; }

C - Maximize the Intersections

题意:

大概就是有2n个点,给你k条已经连起来的边,求如果把剩下没连起来的边连起来,那么最终所有相交线的交点最多有多少个(没太看懂,但是按我理解是这么个意思)

输入

4
4 2
8 2
1 5
1 1
2 1
2 0
10 6
14 6
2 20
9 10
13 18
15 12
11 7

输出

4
0
1
14

思路:

如果我们想要交点最多,那么就要让每队点的小点尽可能的小,另一个大点要大于尽可能多的小点,然后看下图(其实自己画一画就出来了)


从cf题解里面扣的图,可以看出ad和bc连是最优的,得出一个结论,假设有2n个点要连,那么最优解是1 – n+1, 2 – n+2 , … , n-1 – 2n

代码

#include <iostream> #include <algorithm> #include <cstring> #include <vector> #include <cmath> #include <stack> #include <queue> #include <set> #include <map>using namespace std;typedef long long ll; #define SSS \ios_base::sync_with_stdio(0); \cin.tie(0); \cout.tie(0);#define rb(i, a, b) for (int i = (a), i <= (b); i++) #define re(i, a, b) for (int i = (a), i >= (b); i--) #define pii pair<int, int> const int N = 110; const int mod = 1e9 + 7;pii a[N]; int used[500]; int main() {SSS;int t;cin >> t;while (t--){int n, k;cin >> n >> k;n = n * 2;for (int i = 1; i <= n; i++){used[i] = i;a[i].first = 0;a[i].second = 0;}for (int i = 1; i <= k; i++){cin >> a[i].first >> a[i].second;if (a[i].first > a[i].second){int temp = a[i].first;a[i].first = a[i].second;a[i].second = temp;}used[a[i].first] = 1000;used[a[i].second] = 1000;}sort(used + 1, used + n + 1);// for (int i = 1; i <= n; i++)// {// cout << used[i] << " ";// }int mid = (n - k * 2) / 2;// cout << mid << endl;for (int i = k + 1; i <= k + mid; i++){a[i].first = used[i - k];a[i].second = used[mid + i - k];}sort(a + 1, a + n / 2 + 1);// cout << endl;// for (int i = 1; i <= n / 2; i++)// {// cout << a[i].first << " " << a[i].second << endl;// }// cout << endl;int cnt = 0;for (int i = 1; i <= n/2-1; i++){for (int j = i + 1; a[j].first < a[i].second && j <=n/2; j++){if (a[j].second > a[i].second){cnt++;// cout << endl;// cout << i << " " << j << endl;// cout << a[i].first << " " << a[i].second << endl;// cout << a[j].first << " " << a[j].second << endl;// cout << endl;}}}cout << cnt << endl;}return 0; }

D. Array Differentiation

题意

给定一个序列a,是否存在一个序列b,对于任意一个a,都有ai = bj + bk

输入

5
5
4 -7 -1 5 10
1
0
3
1 10 100
4
-3 2 10 2
9
25 -171 250 174 152 242 100 -205 -258

输出

YES
YES
NO
YES
YES

思路

对于序列a和b,我们可以首先求出序列a的所有子集,若序列a的所有子集存在重复的,那么就势必存在一种序列b使得序列a成立

假设序列a的子集有c[i],c[j],c[k],c[l],若c[j] = c[k],则c[j]和c[k]对应的集合可视作一个集合,即序列a至少会少一个数,而一个数量为n的序列是可以被n+1个对应序列所表示的,比如a序列1 2 3 4 5对应的b序列可以为0 1 2 3 4 5,而少一个数则说明对应的序列也可以-1,即至多可以用n个数来表示,所以条件成立

#include <iostream> #include <algorithm> #include <cstring> #include <vector> #include <cmath> #include <stack> #include <queue> #include <set> #include <map>using namespace std;typedef long long ll; #define SSS \ios_base::sync_with_stdio(0); \cin.tie(0); \cout.tie(0); #define caseT \int t; \cin >> t; \while (t--) #define rep(i, a, b) for (int i = (a), i <= (b); i++) #define per(i, a, b) for (int i = (a), i >= (b); i--) #define pii pair<int, int> #define pdd pair<double, double> const int N = 100 + 10; const int mod = 1e9 + 7;int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b); }int lcm(int a, int b) {return a * b / gcd(a, b); }int lowbit(int x) {return x & -x; } int a[N], b[N];int main() {SSS;int t;cin >> t;while (t--){int n;map<int, int> mp;cin >> n;for (int i = 0; i < n; i++){cin >> a[i];}for (int i = 0; i < (1 << n); i++){int sum = 0;for (int j = 0; j < n; j++){if (i & (1 << j))sum += a[j];}mp[sum]++;}// for (auto i = mp.begin(); i != mp.end(); i++)// {// cout << i->first << " ";// }// cout << endl;// cout << mp.size() << " " << (1 << n) << endl;if (mp.size() != (1 << n)){puts("YES");}else{puts("NO");}}return 0; }

总结

以上是生活随笔为你收集整理的Codeforces Global Round 15 ABCD的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。