A题: 小红不想做炸鸡块粉丝粉丝题
签到,稍微优化了下,直接拿出来第一个。
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
const int mod = 998244353;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int a; cin >> a;
int sum = a;
for (int i = 2; i <= 6; i ++ ) {
int x; cin >> x;
sum += x;
}
if (a < sum / 30) cout << "Yes\n";
else cout << "No\n";
return 0;
}
B题: 小红不想做鸽巢原理
贪心。肯定先丢小的。
最后剩下sum%k,从大到小遍历即可。
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
const int mod = 998244353;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n, k; cin >> n >> k;
vector<int> a(n);
ll sum = 0;
for (int i = 0; i < n; i ++ ) {
cin >> a[i];
sum += a[i];
}
sum %= k;
sort(a.begin(), a.end(), greater<>());
int i;
for (i = 0; i < n && sum > 0; i ++ ) {
sum -= a[i];
}
cout << i << endl;
return 0;
}
C题: 小红不想做完全背包(easy)
其实只要想到取模操作就会了。
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
const int mod = 998244353;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n, p; cin >> n >> p;
int a[3] = {};
while (n -- ) {
int x; cin >> x;
x %= 3;
a[x] = 1;
}
if (a[0]) cout << 1 << endl;
else if (a[1] && a[2]) cout << 2 << endl;
else cout << 3 << endl;
return 0;
}
D题: 小红不想做完全背包 (hard)
哎,就是背包,dp[i]为是i倍数的最小物品数,dp[0]是0。
(n3过了,神奇。数据水了吧)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll dp[2010];
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
memset(dp, 0x3f, sizeof dp);
int n, p; cin >> n >> p;
set<ll> s;
bool ok = false;
for (int i = 1; i <= n; i ++ ) {
ll x; cin >> x;
if (x % p == 0) ok = true;
x %= p;
s.insert(x);
}
dp[0] = 0;
if (ok) cout << 1 << endl;
else {
for (ll x : s) {
ll cnt = 1;
ll t = x;
while (cnt <= p) {
for (int i = 0; i <= p; i ++ ) {
if (dp[i] != 0x3f3f3f3f) {
ll now = i + x;
now %= p;
if (now == 0) now = p;
dp[now] = min(dp[now], dp[i] + cnt);
}
}
cnt ++;
x += t;
}
}
cout << dp[p] << endl;
}
return 0;
}
E题: 小红不想做莫比乌斯反演杜教筛求因子和的前缀和
用 i , j 和 x表示k,这样就可以降到n方的复杂度。
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n, m, p, x;
cin >> n >> m >> p >> x;
int cnt = 0;
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ ) {
int nx = x - i * j;
if (nx < 2 * (i + j)) continue;
int k = nx / 2 / (i + j);
if (k * 2 * (i + j) == nx && k <= p) cnt++;
}
cout << cnt << endl;
return 0;
}
F题: 小红不想做模拟题
线段树。节点记录区间A的1的数量,B的1的数量,&起来1的数量。
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
const int N = 1e5 + 9;
int a[N], b[N];
struct Node{
int l, r;
int c1, c2, c;
int lz1, lz2;
}tr[4 * N];
void pushup(int u) {
auto &root = tr[u], &left = tr[u << 1], &right = tr[u << 1 | 1];
root.c1 = left.c1 + right.c1;
root.c2 = left.c2 + right.c2;
root.c = left.c + right.c;
}
void build(int u, int l, int r) {
if (l == r) {
tr[u] = {l, r, a[l], b[l], a[l] & b[l]};
}else {
tr[u] = {l, r};
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
}
void pushdown(int u) {
auto &root = tr[u], &left = tr[u << 1], &right = tr[u << 1 | 1];
if (root.lz1) {
root.lz1 = 0, left.lz1 = 1, right.lz1 = 1;
left.c1 = left.r - left.l + 1;
left.c = left.c2;
right.c1 = right.r - right.l + 1;
right.c = right.c2;
}
if (root.lz2) {
root.lz2 = 0, left.lz2 = 1, right.lz2 = 1;
left.c2 = left.r - left.l + 1;
left.c = left.c1;
right.c2 = right.r - right.l + 1;
right.c = right.c1;
}
}
void modify(int u, int l, int r, char op) {
if (tr[u].l >= l && tr[u].r <= r) {
if (op == 'A') {
tr[u].c1 = tr[u].r - tr[u].l + 1;
tr[u].c = tr[u].c2;
tr[u].lz1 = 1;
}else {
tr[u].c2 = tr[u].r - tr[u].l + 1;
tr[u].c = tr[u].c1;
tr[u].lz2 = 1;
}
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) modify(u << 1, l, r, op);
if (r > mid) modify(u << 1 | 1, l, r, op);
pushup(u);
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n; cin >> n;
string A, B; cin >> A >> B;
for (int i = 0; i < n; i ++ ) {
a[i + 1] = (A[i] == '1');
b[i + 1] = (B[i] == '1');
}
build(1, 1, n);
int q; cin >> q;
while (q -- ) {
char op; int l, r;
cin >> op >> l >> r;
modify(1, l, r, op);
cout << tr[1].c << endl;
}
return 0;
}