C
题意:给你一个长为N的序列A,并由他构成一个无限长的序列AAAAA....(至少对于输入数据是这样的),问你在这个无限长的序列中,前多少个数字的和会超过X
#include <iostream>
using namespace std;
const int N = 100010;
#define int long long
int n, x;
int a[N];
signed main(){
cin >> n;
int sum = 0;
for(int i = 0; i < n; i ++){
cin >> a[i];
sum += a[i];
}
cin >> x;
int p = x % sum, q = (x / sum) * n;
int t = 0;
for(int i = 0; i < n; i ++){
t += a[i];
if(t <= p) q ++;
}
q ++;
cout << q << endl;
}
D
题意:给你一个整数序列\(A=(A_1,…,A_N),A_i\in\{0,1,...,9\}\),定义两种操作F和G
F操作:将序列最左边的两个数字a, b合并成(a + b) % 10
G操作:将序列最左边的两个数字a, b合并成(a * b) % 10
最终序列剩下一个数字t的时候,问分别有多少种FG操作组合能够让t为0,...,9
方法:dp
状态:\(f(i, j)\),表示第i次操作后,所获得的数字为j的FG操作组合的数目
状态计算:
\[f(i, (p + i) \% 10) = f(i, (p + i) \% 10) + f(i, p)\\
f(i, (p * i) \% 10) = f(i, (p * i) \% 10) + f(i, p)\\
\]
初始条件:\(f(0, A[0]) = 1\)
#include<iostream>
using namespace std;
const int N = 100010, mod = 998244353;
int f[N][10];
int n, a[N];
int main(){
cin >> n;
for(int i = 0; i < n; i ++) cin >> a[i];
f[0][a[0]] = 1;
for(int i = 1; i < n; i ++){
for(int j = 0; j <= 9; j ++){
int &p = f[i][(a[i] + j) % 10];
int &q = f[i][(a[i] * j) % 10];
p = (p + f[i - 1][j]) % mod;
q = (q + f[i - 1][j]) % mod;
}
}
for(int i = 0; i <= 9; i ++) cout << f[n - 1][i] << endl;
return 0;
}