2020劳动节四天乐(3)题解 Gym 102348(部分题解,后续更新)
A - Yellow Cards Gym - 102348A
题意:给你n张黄牌,第一队有a1个人,每人拿k1张黄牌就罚下;第二队有a2个人,每人拿k2张黄牌就罚下,求最小淘汰人数和最大淘汰人数
思路:贪心,最大淘汰人数比较好想,就优先淘汰k比较少的队伍,多了的就淘汰另一队伍分析就完事了。
最小淘汰人数就是每人都拿k-1张黄牌,多了的黄牌多一个淘汰一个就这样。
呈上代码!
1 #include<iostream> 2 #include<algorithm> 3 #include<vector> 4 #include<map> 5 #include<cstring> 6 #include<cmath> 7 using namespace std; 8 #define ll long long 9 #define double long double 10 #define eps 0.0000000001//偏差值1e8 11 const int N = 1e5 + 5; 12 const int mod = 1e9 + 9; 13 int main() 14 { 15 ll i, j, k; 16 ll n, m, t; 17 ll ans1 = 0,ans2=0; 18 ll a1, a2, k1, k2; 19 cin >> a1 >> a2 >> k1 >> k2>>n; 20 if (k1 > k2) 21 { 22 23 24 if (k2 * a2 >= n) 25 { 26 ans2 = n / k2; 27 } 28 else 29 { 30 ans2 = (n - (a2 * k2)) / k1 + a2; 31 } 32 if (a1*(k1-1)+a2*(k2-1)>=n) 33 { 34 ans1 = 0; 35 } 36 else 37 { 38 n -= a1 * (k1 - 1) + a2 * (k2 - 1); 39 ans1 = n; 40 } 41 cout << ans1 << " " << ans2 << endl; 42 } 43 else 44 { 45 if (k1 * a1 >= n) 46 { 47 ans2 = n / k1; 48 } 49 else 50 { 51 ans2 = (n - (k1 * a1)) / k2 + a1; 52 } 53 if (a1 * (k1 - 1) + a2 * (k2 - 1) >= n) 54 { 55 ans1 = 0; 56 } 57 else 58 { 59 n -= a1 * (k1 - 1) + a2 * (k2 - 1); 60 ans1 = n; 61 } 62 cout << ans1 << " " << ans2 << endl; 63 } 64 }
D - Ticket Game Gym - 102348D
题意:给你个字符串包含‘?’和数字,依次轮流将一个?变成0-9的数字,Monocarp先操作改变,如果0-n/2的和等于n/2-n的和,则Bicarp胜利,否则Monocarp胜利
思路:博弈论,最简单想法就是Monocarp想办法在?多的一边填一个大数,使而Bicarp想办法在?多的地方填一个小的数,这样权衡,如果两边的问号个数不相等且已知和不相等,Monocarp会填多?的那边一半个9,Bicarp会填0(就他俩优先填问号多的一边,以达胜利)
详情看代码吧!
1 #include<iostream> 2 #include<algorithm> 3 #include<vector> 4 #include<map> 5 #include<cstring> 6 #include<cmath> 7 using namespace std; 8 #define ll long long 9 #define double long double 10 #define eps 0.0000000001//偏差值1e8 11 const int N = 1e5 + 5; 12 const int mod = 1e9 + 9; 13 int main() 14 { 15 ll i, j, k; 16 ll n, m, t; 17 ll sum1 = 0,sum2=0; 18 ll count1 = 0, count2 = 0; 19 string s; 20 cin >> n >> s; 21 for (i = 0; i < n / 2; i++) 22 if (s[i] >= '0' && s[i] <= '9') 23 sum1 += s[i] - '0'; 24 else 25 count1++; 26 for (i = n / 2; i < n; i++) 27 if (s[i] >= '0' && s[i] <= '9') 28 sum2 += s[i] - '0'; 29 else 30 count2++; 31 if (count1 ==0&& count2==0) 32 { 33 if (sum1 == sum2) 34 cout << "Bicarp"; 35 else 36 cout << "Monocarp"; 37 } 38 else if (count1 == count2) 39 { 40 if (abs(sum1 - sum2) >= 1) 41 cout << "Monocarp"; 42 else 43 cout << "Bicarp"; 44 } 45 else 46 { 47 ll ans1 = count1 * 9/2 + sum1, ans2 = count2 * 9/2 + sum2; 48 if (ans1==ans2) 49 cout << "Bicarp"; 50 else 51 cout << "Monocarp"; 52 } 53 }
F - The Number of Products Gym - 102348F
题意:给你n个数,算出区间【L,R】的正子段数,负子段数,零子段数。
思路:简单dp,dp[i][0]表示正子段数,dp[i][1]表示负子段数,零子段数则用总和n*(n+1)/2-负子段数-正子段数就可以了
当a[i]==0时重新把dp[i][0]和dp[i][1]初始化为0就好,这样算到2 0 5 这样子段
看看代码转移方程吧!
1 #include<iostream> 2 #include<algorithm> 3 #include<vector> 4 #include<map> 5 #include<stack> 6 #include<cstring> 7 #include<cmath> 8 using namespace std; 9 #define ll long long 10 #define double long double 11 #define eps 0.0000000001//偏差值1e8 12 const int N = 2e5 + 5; 13 const int mod = 1e9 + 9; 14 ll a[N],dp[N][2];//0为正,1为负 15 int main() 16 { 17 ll i, j, k; 18 ll n, m, t; 19 ll count1 = 0, count2 = 0; 20 cin >> n; 21 for (i = 1; i <= n; i++) 22 { 23 cin >> a[i]; 24 } 25 for (i = 1; i <= n; i++) 26 { 27 if (a[i] == 0) 28 dp[i][0] = dp[i][1] = 0; 29 else if (a[i] < 0) 30 { 31 dp[i][0] = dp[i - 1][1]+1; 32 dp[i][1] = dp[i - 1][0]; 33 } 34 else 35 { 36 dp[i][0] = dp[i - 1][0]; 37 dp[i][1] = dp[i - 1][1] + 1; 38 } 39 } 40 ll ans1 = 0, ans2 = 0, ans3 = 0; 41 for (i = 1; i <= n; i++) 42 { 43 ans1 += dp[i][0];//统计正个数 44 ans2 += dp[i][1];//统计负数个数 45 } 46 ans3 += n * (n + 1) / 2 - ans1 - ans2;//原本总共n*(n+1)/2子段个 47 cout << ans1 << " " << ans3 << " " << ans2 << endl; 48 49 50 }
G - Swap Letters Gym - 102348G
题意:给你字符串长度相等s1,s2,可以操作多次s1与s2的字符交换操作,使得s1==s2,问最少操作次数
思路:模拟,用两个栈记录俩字符不相同的位置(用数据结构deque queue vector都可以),先计算a的个数b的个数若为奇数,则为-1,否则如果ab类型是奇数个(s1[i]是a,s2[i]是b),则要找一个位置进行自我交换,使得俩类型都是偶数个
大内容看代码吧!
1 #include<iostream> 2 #include<algorithm> 3 #include<vector> 4 #include<map> 5 #include<stack> 6 #include<cstring> 7 #include<cmath> 8 using namespace std; 9 #define ll long long 10 #define double long double 11 #define eps 0.0000000001//偏差值1e8 12 const int N = 1e5 + 5; 13 const int mod = 1e9 + 9; 14 typedef pair<ll, ll> PII; 15 stack<ll>v1; 16 stack<ll>v2; 17 vector<PII>ans; 18 int main() 19 { 20 ll i, j, k; 21 ll n, m, t; 22 ll ans1 = 0,ans2=0; 23 ll count1 = 0, count2 = 0; 24 string s1,s2; 25 cin >> n; 26 cin >> s1 >> s2; 27 for (i = 0; i < n; i++) 28 { 29 if (s1[i] == 'a') 30 count1++; 31 else 32 count2++; 33 if (s2[i] == 'a') 34 count1++; 35 else 36 count2++; 37 } 38 if (count2 % 2 != 0 || count1 % 2 != 0) 39 cout << -1 << endl; 40 else 41 { 42 for (i = 0; i < n; i++) 43 { 44 if (s1[i] != s2[i]) 45 { 46 if (s1[i] == 'a') 47 v1.push(i + 1);//记录s1中a的位置 48 else 49 v2.push(i + 1);//记录s2中的b位置 50 } 51 } 52 if (v1.size() & 1)//v1,v2都为奇数个,找一个v1放到v2 53 { 54 ll pos = v1.top(); 55 v1.pop(); 56 ans.push_back(make_pair(pos, pos)); 57 v2.push(pos); 58 } 59 while (!v1.empty()) 60 { 61 ll pos1 = v1.top(); 62 v1.pop(); 63 ll pos2 = v1.top(); 64 v1.pop(); 65 ans.push_back(make_pair(pos1, pos2)); 66 } 67 while (!v2.empty()) 68 { 69 ll pos1 = v2.top(); 70 v2.pop(); 71 ll pos2 = v2.top(); 72 v2.pop(); 73 ans.push_back(make_pair(pos1, pos2)); 74 } 75 cout << ans.size() << endl; 76 for (i = 0; i < ans.size(); i++) 77 cout << ans[i].first << " " << ans[i].second << endl; 78 } 79 80 }