牛客周赛 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';
}

