牛客周赛 Round 3 题解
A.游游的7的倍数
思路:每十个数里一定有至少一个7的倍数,因此枚举个位即可。
void solve() { cin >> n; for (int i = 0; i <= 9; ++i) { if ((n * 10 + i) % 7 == 0) { cout << n << i << '\n'; break; } } }
B.游游的字母串
思路:枚举。
枚举将字符串中的所有字符变成某个字母所需的步数,取最小值即可。
由于本题中的字母串是一个环,所以每一个字符还应取到达目标字符的最小步数。
void solve() { int ans = 1e9; string s; cin >> s; for (int i = 0; i < 26; ++i) { int cnt = 0; for (int j = 0; j < s.size(); ++j) { int tmp = abs(s[j] - 'a' - i); cnt += min(tmp, 26 - tmp); } ans = min(ans, cnt); } cout << ans << '\n'; }
C.游游的水果大礼包
思路:枚举(还有一点数学?)。
枚举第一个礼包打包的数量,那么第二个礼包打包的数量就可以算出来了。
由此,我们可以取这些枚举方法中的最大值作为答案。
void solve() { cin >> n >> m >> a >> b; int ans = 0; for (int i = 0; 2 * i <= m && i <= n; ++i) { int cnt = 0; int x1 = i, y1 = 2 * i; int x2 = (n - i) / 2, y2 = (m - 2 * i); cnt = x1 * b + min(x2, y2) * a; ans = max(ans, cnt); } cout << ans << '\n'; }
D.游游的矩阵权值
思路:贪心。
透过题意我们可以发现,在矩阵角落的数字只会加两次,在边上的数字会加三次,在矩阵内部的数字会加四次。
那么我们只要让最小的数字在角落和边缘上,用等差数列求和即可。
由于需要取模运算,我这里用费马小定理求了一个逆元。
int quick(int a,int k,int p){ int res=1; while(k){ if(k&1) res=1ll*a*res%p; a=1ll*a*a%p; k>>=1; } return res; } void solve() { cin >> n; cout << ((10ll * 2 + 4ll * (n - 2) % mod * (5 + (4 + (4ll * (n - 2)))) % mod * quick(2, mod - 2, mod) * 3) % mod + ((n - 2ll) * (n - 2)) % mod * (n * n % mod + (5 + 4 * (n - 2ll) % mod)) * 2 % mod) % mod << '\n'; }
这个代码可能更清晰一些:
int quick(int a, int k, int p) { int res = 1; while (k) { if (k & 1) res = 1ll * a * res % p; a = 1ll * a * a % p; k >>= 1; } return res; } void solve() { cin >> n; int part1 = 20; int part2 = 4ll * (n - 2) % mod * (5 + (4 + (4 * (n - 2)))) % mod * quick(2, mod - 2, mod) * 3 % mod; int part3 = ((n - 2ll) * (n - 2)) % mod * ((1ll * n * n % mod + (5 + 4 * (n - 2ll))) * 2) % mod; cout << ((part1 + part2) % mod + part3) % mod << '\n'; }