2020劳动节训练赛
Posted sympa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020劳动节训练赛相关的知识,希望对你有一定的参考价值。
A - Yellow Cards Gym - 102348A
题目大意:足球比赛,两个队分别有a1,a2名队员,每个队的队员分别得到k1和k2张黄牌罚下,这场比赛一共出示了n张黄牌,问最大和最小罚下多少队员。另外比赛不会中断,即使全场都被罚下(阴 间 比 赛)。
思路:贪心。求最大先罚罚下需要黄牌少的队伍。求最小把全场球员罚到每人只差一张黄牌就会被罚下。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 int main(){ 4 int a1, a2, k1, k2, n,max=0,min=0; 5 cin >> a1 >> a2 >> k1 >> k2 >> n; 6 if (a1 * (k1 - 1) + a2 * (k2 - 1) >= n)min = 0; 7 else min = n - (a1 * (k1 - 1) + a2 * (k2 - 1)); 8 if (k1 >= k2) { 9 if (n <= a2 * k2)max = n / k2; 10 else max = a2 + (n - a2 * k2) / k1; 11 } 12 else if (k2 > k1) { 13 if (n <= a1 * k1)max = n / k1; 14 else max = a1 + (n - a1 * k1) / k2; 15 } 16 cout << min << " " << max << endl; 17 return 0; 18 }
D - Ticket Game Gym - 102348D
题目大意:有一个字符串,包含数字和‘?‘,小M和小B在‘?‘处填上任意数字,如果左半边数字和等于右半边数字和,小B胜,否则小M胜利。小M先手,问谁胜。
思路:博弈,分类讨论下,设我是小B,先统计左右两边问号数量和左右数字的和,如果左右数字和一样多,只有左右空一样多时,小M填多少,我小B就跟着填多少,小B必胜,反之小M必胜。
再考虑左右数字和不等的情况:如果左边和小,并且左边空少或和右边空一样多,小M只要疯狂往右塞大数,我小B就gg了。如果左边空多,小M肯定还是疯狂往右塞大数,但我小B还是有机会的,我只要保证当小M把右边塞完大数,只能不得不往左边塞小数时,左边的和可以追上右边我小B就有机会了;但我还是不能保证我能赢,因为如果追上了但超过了该怎么办?所以还要再讨论下。首先,因为是小M先手,所以设本来左边有n个空,右边有m个空,当小M往右边塞完大数时,左边还有n-m个空,这时,是小m先塞,所以如果最后一个空轮到小M塞数的话,他就为所欲为了,我gg。所以如果n-m是奇数,小M必胜。如果n-m为偶数,每轮小M塞0我塞9,左边的和可以追上9,但我朋友小M可不是蠢蛋!他肯定不会让我占据主动,所以,我唯一能保证的是,我可以让每轮我和他的数字和固定增加9。所以,只有剩余轮次*9=左右之差时,才能保证小B胜利。右边和小一个道理,就不多赘述了。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 int main(){ 4 ios::sync_with_stdio(false); 5 int n,ff=0; 6 cin >> n; 7 string s; 8 int m,kong_left=0,kong_right=0,sum_left=0,sum_right=0,aihei; 9 cin >> s; 10 for (int i = 0; i < n / 2; i++) { 11 if (s[i] == ‘?‘)kong_left++; 12 else { aihei = s[i] - ‘0‘; sum_left += aihei; } 13 } 14 for (int i = n/2; i < n; i++) { 15 if (s[i] == ‘?‘)kong_right++; 16 else{ aihei = s[i] - ‘0‘; sum_right += aihei; } 17 } 18 if (sum_left > sum_right) { 19 if (kong_left >= kong_right)ff = 1; 20 else { 21 if ((kong_right - kong_left) % 2 != 0)ff = 1; 22 else if ((sum_left - sum_right) != (kong_right - kong_left) / 2 * 9)ff = 1; 23 else ff = 2; 24 } 25 } 26 if (sum_left < sum_right) { 27 if (kong_left <= kong_right)ff = 1; 28 else { 29 if ((kong_left - kong_right) % 2 != 0)ff = 1; 30 else if ((sum_right - sum_left) != (kong_left - kong_right) / 2 * 9)ff = 1; 31 else ff = 2; 32 } 33 } 34 if (sum_left == sum_right) { 35 if (kong_left != kong_right)ff = 1; 36 else ff = 2; 37 } 38 if (ff == 1)cout << "Monocarp" << endl; 39 else cout << "Bicarp" << endl; 40 return 0; 41 }
F - The Number of Products Gym - 102348F
题目大意:给一个数组,求分别有多少个子区间乘积为负数,0,正数。
思路:这叫前缀 积?管它的,统计前1~n个数有多少正数,负数,遇到0重新统计。
上代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 int a[200001], c[200001]; 4 int main() { 5 ios::sync_with_stdio(false); 6 long long n, sum = 0, ans = 0, fu = 0, zheng = 0, fuz = 0, zeroz = 0, zhengz = 0,change,ka=0; 7 cin >> n; 8 a[0] = 0; 9 for (int i = 1; i <= n; i++) { 10 cin >> c[i]; 11 if (c[i] < 0) 12 sum++; 13 a[i] = sum; 14 } 15 for (int i = 1; i <= n; i++) { 16 if (c[i] > 0) { 17 zheng++; 18 zhengz += zheng; 19 fuz += fu; 20 zeroz += ka; 21 } 22 if (c[i] < 0) { 23 change = fu; 24 fu = zheng; 25 zheng = change; 26 fu++; 27 zhengz += zheng; 28 fuz += fu; 29 zeroz += ka; 30 } 31 if (c[i] == 0) { 32 zeroz += i; 33 zheng = 0; 34 fu = 0; 35 ka = i; 36 } 37 } 38 cout << fuz << " " << zeroz << " " << zhengz << endl; 39 return 0; 40 }
G - Swap Letters Gym - 102348G
题目大意:给两个只有字符a和b的长度相等字符串,从两个字符串分别选一个字符进行交换多次,问至少交换多少次能使两字符串相等,若不能就打印-1.
思路:统计两字符串相同下标的组合分别的数量,aa和bb这种不要管,因为没必要换,只要求ab和ba的数量。ab和ba数量的和若为奇数,便无法通过交换使两字符串相同。别忘了记录下标,因为要输出方法。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 int a[200001] = {0}, b[200001] = { 0 }; 4 int main(){ 5 int n,ans1=0,ans2=0; 6 string s1, s2; 7 cin >> n; 8 cin >> s1 >> s2; 9 for (int i = 0; i < n; i++) { 10 if (s1[i] == ‘a‘ && s2[i] == ‘b‘) { a[ans1] = i + 1; ans1++; } 11 if (s1[i] == ‘b‘ && s2[i] == ‘a‘) { b[ans2] = i + 1; ans2++; } 12 } 13 if (ans1%2==0&&ans2%2!=0|| ans2 % 2 == 0 && ans1 % 2 != 0)cout << "-1" << endl; 14 else { 15 if (ans1 % 2 == 0) { 16 cout << ans1 / 2 + ans2 / 2 << endl; 17 for (int i = 0; i < ans1; i = i + 2) 18 cout << a[i] << " " << a[i + 1] << endl; 19 for (int i = 0; i < ans2; i = i + 2) 20 cout << b[i] << " " << b[i + 1] << endl; 21 } 22 else { 23 cout << ans1 / 2 + ans2 / 2+2 << endl; 24 for (int i = 0; i < ans1-1; i = i + 2) 25 cout << a[i] << " " << a[i + 1] << endl; 26 for (int i = 0; i < ans2-1; i = i + 2) 27 cout << b[i] << " " << b[i + 1] << endl; 28 cout << a[ans1 - 1] << " " << a[ans1- 1] << endl; 29 cout << a[ans1 - 1] << " " << b[ans2 - 1] << endl; 30 } 31 } 32 return 0; 33 }
I - Moonbound
阅读理解题,奇怪的坑,不放代码了,注意不要1和2分别全部输出。
以上是关于2020劳动节训练赛的主要内容,如果未能解决你的问题,请参考以下文章