A--R全部为模拟不上代码,重点讲解一下最后两题
S 小乐乐与字符串
https://ac.nowcoder.com/acm/contest/1877/S
从前往后遍历记录C的个数,表示当前字符前有几个C字符。从后往前遍历记录N的个数,表示当前字符之后的N的字符个数
最后从前往后遍历数组,当当前字符为H时,有numC*numN种情况,每次相加求和即为答案。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=8000;
int num2[MAXN+11];
int main() {
string s;
cin>>s;
for(int i=s.length()-1;i>=0;i--) {
num2[i]=num2[i+1];
if(s[i]=='N')
num2[i]++;
}
long long cnt=0;
for(int i=0;i<s.length();i++) {
if(s[i]=='C') {
for(int j=i+1;j<s.length();j++) {
if(s[j]=='H')
cnt+=num2[j];
}
}
}
printf("%lld\n",cnt);
return 0;
}
T 小乐乐与二段数
https://ac.nowcoder.com/acm/contest/1877/T
专门记录一下,传送门
第一次见这种解法,数论只会GCD。%%%
#include<cstdio>
#include<cstring>
#include <algorithm>
using namespace std;
int ones[9999],tens[999], n, i, j, k, s, t, api, apj, aps, apt;
bool ck() {
int p, r;
if (i > 5)
return 1;
p = s;
r = t;
for (int q = 0; q < j; q++)
p = p * 10 + s;
for (int q = 0; q < i - j; q++)
p = p * 10;
for (int q = 1; q < i - j; q++)
r = r * 10 + t;
return p + r > n;
}
int main() {
while (scanf("%d",&n), n) {
printf("%d: ", n);
if (n == 1) {
puts("10");
continue;
}
ones[0] = 1;
tens[0] = 1;
for (i = 1; i < 9999; i++)
ones[i] = (ones[i - 1] * 10 + 1) % n;
for (i = 1; i < 999; i++)
tens[i] = tens[i - 1] * 10 % n;
for (i = 1, aps = 0; i < 9999; i++) {
k = 0;
if ((n % 10 == 0 || n % 25 == 0) && i > 11)
k = i - 11;
for (j = k; j < i; j++)
for (s = 1; s < 10; s++)
for (t = 0; t < (n % 10 ? 10 : 1); t++)
if (t != s && (((long long)ones[j]) * tens[i - j] * s + ones[i - j - 1] * t) % n == 0 && ck() &&
(!aps || s < aps || s == aps && j > apj && s < apt)) {
api = i;
apj = j;
aps = s;
apt = t;
}
if (aps)
break;
}
for (int x = 0; x < apj + 1; x++)
printf("%d", aps);
for (int x = 0; x < api - apj; x++)
printf("%d", apt);
printf("\n");
}
return 0;
}