一、D题(简单)
链接:https://ac.nowcoder.com/acm/contest/9983/D
题目描述
还有一个周就要过年啦!这一天牛牛盯着新的台历出神,他突然想知道对于第n年来说,大于n且与n的数位和相同的最小年份是多少。
一个数字的数位和等于他各数位上的数字之和,例如2021的数位和等于2+0+2+1=5
输入描述:
一个正整数n。2021≤n≤2030
输出描述:
输出一个正整数代表答案。
示例1
输入2025
输出2034
说明:2034是比2025大的且数位和等于9的最小正整数
#include<algorithm> #include<iostream> #include<cmath> #include<cstring> using namespace std; typedef long long ll; const int maxn = 1e7 + 9; int main() { int n; cin >> n; if (n < 2030) { cout << n + 9 << endl; } else { cout << 2102 << endl; } }
二、H题 数字串(字符串,模拟)
链接:https://ac.nowcoder.com/acm/contest/9983/H
题目描述
牛牛发现了一种方法可以将只包含小写字母的字符串按照以下方式使其转换成一个数字串:
取其中的每个字母,a转换为1,b转换为2, z转换为26,然后将这些数字拼接起来。
例如,abcz可以转换为12326。
现在给出一个只包含小写字母的字符串S,你需要找到一个只包含小写字母的字符串T,使得两个串不相同但是能转换成相同的数字串。
输入描述:
一行一个长度不超过10^{6}的小写字母字符串S。
输出描述:
一行一个长度不超过2×10^{6}的小写字母字符串T。
如果无解,请输出-1。如果答案有解且你输出的字符串包含了除了小写字母以外的字符或长度超过了2×10^{6},那么你会得到“答案错误”的返回结果。
否则如果答案有解且你的答案与输入的字符串可以转换为一样的数字串,那么你的答案会被认为是正确的。
示例1:输入cwc
输出cbcc 说明:cwc和cbcc转换成的数字串都是3233
示例2:输入ccc输出-1
理解:忘记了一种情况,小的转化为大的
#include<iostream> #include<cmath> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; int main() { string s; cin >> s; s += '#'; int len = s.length(); int p = -1; string s1 = ""; for (int i = 0; i < len; i++) { if (s[i] >= 'k' && s[i] <= 's') { p = i; break; } if (s[i] >= 'u' && s[i] <= 'z') { p = i; break; } if (s[i] == 'a' &&s[i+1]!='j'&&s[i+1]!='t') { p = i; break; } if (s[i] == 'b' && s[i + 1] <='f') { p = i; break; } s1 += s[i]; } if (p >=0 ) { if (s[p] > 'b') { int y = s[p] - 'a' + 1; char f = 'a' - 1 + (s[p] - 'a' + 1) / 10; char ff = 'a' - 1 + (s[p] - 'a' + 1) % 10; s1 += f; s1 += ff; for (int i = p + 1; i < len-1; i++) { s1 += s[i]; } cout << s1 << endl; } else { int y = s[p] - 'a' + 1; int yy = s[p+1] - 'a' + 1; char num = (y * 10 + yy) + 'a' - 1; //cout << y << " " << yy << " " << num << endl; s1 += num; for (int i = p + 2; i < len - 1; i++) { s1 += s[i]; } cout << s1 << endl; } } else { cout << -1 << endl; } }
三、J题 加法和乘法(博弈)
链接:https://ac.nowcoder.com/acm/contest/9983/J
题目描述 :
有一天牛牛和牛妹在做游戏,规则如下:
桌面上摆着n\mathit nn张纸牌,每张纸牌上写着一个正整数,由牛牛先手轮流执行以下操作:
1.如果桌面上只剩一张纸牌,游戏结束,这张纸牌上的数字如果是奇数则牛牛胜利,反之牛妹胜利。
2.当前行动玩家选择两张纸牌,设上面的数字分别为X,Y,接下来玩家从加法和乘法中选择一个并应用到这两个数字上,得到结果为Z,接下来将选择的两张纸牌丢弃,并拿一张新的纸牌放到桌面上,在上面写上Z。
假设双方均以最优策略行动,最后谁会赢?
理解:对于n为偶数的时候,想错了
如果只有一个数,那么这个数是奇数则牛牛赢,否则牛妹赢。
如果不止一个数,那么假设有奇数个数,显然是牛妹赢。因为剩余2个数的时候,牛妹做最后一次操作,无论什么情况一定都能生成两个偶数(如果剩两个奇数就做加法,如果存在偶数就做乘法)。
假设有偶数个数,牛妹要做的就是让最后剩余2个偶数即可。牛牛每次最多可以消除一个偶数,牛妹每次最多可以生成一个偶数。所以如果初始状态的偶数不小于2个,则牛妹赢;否则牛牛赢。
如果不止一个数,那么假设有奇数个数,显然是牛妹赢。因为剩余2个数的时候,牛妹做最后一次操作,无论什么情况一定都能生成两个偶数(如果剩两个奇数就做加法,如果存在偶数就做乘法)。
假设有偶数个数,牛妹要做的就是让最后剩余2个偶数即可。牛牛每次最多可以消除一个偶数,牛妹每次最多可以生成一个偶数。所以如果初始状态的偶数不小于2个,则牛妹赢;否则牛牛赢。
#include<algorithm> #include<cmath> #include<cstring> #include<iostream> using namespace std; typedef long long ll; int n; int main() { cin >> n; int f = 1; if (n==1) { int a; cin >> a; if (a % 2 == 0)f = 0; } else if(n==2){ int a, b; cin >> a >> b; if (a % 2 == 0 && b % 2 == 0)f = 0; else f = 1; } else { int a; int k = 0; for (int i = 1; i <= n; i++) { cin >> a; if (a % 2 == 0)k++; } if (k >=2) { f = 0; } else { if (n % 2 == 1)f = 0; else f = 1; } } if (f == 0)cout << "NiuMei" << endl; else cout << "NiuNiu" << endl; }
四、糖果 (并查集)
链接:https://ac.nowcoder.com/acm/contest/9983/G
在一个幼儿园里面有n个小朋友,分别编号1,2,...,n。在这些小朋友中有一些小朋友互为朋友关系,总共有m对朋友。
作为幼儿园老师,你想买一些糖果分给小朋友,你知道第i个小朋友想要至少ai个糖果,否则他就会不开心。
同时,如果一个小朋友得到的糖果数小于他某个朋友得到的糖果数,他也会不开心。
请问你最少买多少糖果才能保证每个小朋友都不会不开心呢?
#include<bits/stdc++.h> using namespace std; #define ll long long ll fa[1000100]; ll a[1000100]; int f(int x){ if(x==fa[x])return x; return fa[x]=f(fa[x]); } int main(){ ll n,m,i; cin>>n>>m; for(i=1;i<=n;i++)cin>>a[i],fa[i]=i; for(i=0;i<m;i++){ int x,y; cin>>x>>y; int p=f(x),q=f(y); fa[p]=q; a[p]=a[q]=max(a[p],a[q]); } ll res=0; for(i=1;i<=n;i++)res+=a[f(i)]; cout<<res; }
补并查集和博弈
浙公网安备 33010602011771号