A. 321-like Checker
string solve() {
string s; cin >> s;
int n = s.size();
for (int i = 1; i < n; i ++)
if (s[i - 1] <= s[i]) return no;
return yes;
}
B. Cutoff
int solve() {
int n, x; cin >> n >> x;
int a[100];
int maxx = 0, minn = 100, sum = 0;
for (int i = 0; i < n - 1; i ++) {
cin >> a[i];
maxx = max(maxx, a[i]);
minn = min(minn, a[i]);
sum += a[i];
}
for (int i = 0; i <= 100; i ++) {
int res = sum + i - min(minn, i) - max(maxx, i);
if (res >= x) return i;
}
return -1;
}
C. 321-like Searcher
const int N = 3.7e6;
int n;
ll a[N];
void dfs(ll num) {
a[n ++] = num;
if (num % 10 == 0) return;
for (int i = 0; i < num % 10; i ++) dfs(num * 10 + i);
}
ll solve() {
int x; cin >> x;
for (int i = 0; i <= 9; i ++) dfs(i);
sort(a, a + n);
return a[x];
}
D. Set Menu
const int N = 2e5 + 2;
int a[N], b[N];
ll pre[N];
ll solve() {
int n, m, x; cin >> n >> m >> x;
for (int i = 1; i <= n; i ++) cin >> a[i];
for (int i = 1; i <= m; i ++) cin >> b[i];
sort(a + 1, a + n + 1);
sort(b + 1, b + m + 1);
for (int i = 1; i <= m; i ++) pre[i] = pre[i - 1] + b[i];
ll res = 0;
for (int i = 1; i <= n; i ++) {
int t = upper_bound(b + 1, b + m + 1, x - a[i] - 1) - b - 1;
res += (ll)(m - t) * x + (ll)t * a[i] + pre[t];
}
return res;
}
F. #(subset sum = K) w
题意 n , 1 ≤ n ≤ 5000 n,1\le n\le 5000 n,1≤n≤5000 次操作,每次操作多重集合 S S S,将其中加入或删除一个数 x , 1 ≤ x ≤ 5000 x,1\le x\le 5000 x,1≤x≤5000,对于每次操作后,问集合中的数有多少种组合,其和为 m m m
题解 对于新增数 x x x,对于区间 [ x , m ] [x,m] [x,m] 中数 i i i 的贡献为 f [ i − x ] f[i-x] f[i−x],逆序遍历 i : m → x i:m\rightarrow x i:m→x,是为了防止前面增加的贡献影响后面的
对于删除数 x x x,同理,此时要正序遍历
const int mod = 998244353;
const int N = 5e3 + 2;
ll f[N] = {1};
int main() {
int n, m; cin >> n >> m;
while (n --) {
char c; int x; cin >> c >> x;
if (c == '+')
for (int i = m; i >= x; i --)
(f[i] += f[i - x]) %= mod;
else
for (int i = x; i <= m; i ++)
(f[i] += mod - f[i - x]) %= mod;
cout << f[m] << endl;
}
return 0;
}