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 }
原文地址:https://www.cnblogs.com/ch-hui/p/12828893.html