A
直接推公式,没有饭堂点。
1 2 3 4 5 6 7 8 9 10
| #include <bits/stdc++.h> using namespace std; #define int long long int d, f;
signed main() { cin >> d >> f; cout << (((d - f) / 7) * 7 + f) + 7 - d; return 0; }
|
B
我们先用一层循环循环枚举所有可能的起始位置,枚举到 $n - m$,其实就是枚举 $s$ 从 $i$ 开始长度为 $m$ 的字串。
然后再用一层循环比较 $s_{i+j}$ 和 $t_j$,然后计算贡献,贡献公式为:
$$
(s_{i+j}-t_j+10)\mod 10
$$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include <bits/stdc++.h> using namespace std; #define int long long int n, m, Min = 1e9; string s, t;
signed main() { cin >> n >> m >> s >> t; for (int i = 0;i <= n - m;i++) { int now = 0; for (int j = 0;j < m;j++) { now += (((s[i + j] - '0') - (t[j] - '0')) + 10) % 10; } Min = min(Min, now); } cout << Min; return 0; }
|
C
emmm……
这题我们可以用一个栈来维护当前序列,每个栈内元素为一个二元组 $(val,len)$ 表示这个段的值,这个段的长度,我们把相同连续的段压缩为 $1$ 段,然后兄左到右扫描这个数组,如果栈顶的值和当选值相同,则栈顶元素的 $len+1$,否则说明有新段,搞个新段压入栈,如果每次 $len > 4$ 就删掉 $4$ 个,如果 $len = 0$ 则弹栈,然后可能有连锁反应,要接着检查。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| #include <bits/stdc++.h> using namespace std; #define int long long const int N = 1e6 + 5; int n, a[N];
struct node { int v, l; };
stack<node>sk;
void asd() { for (;!sk.empty() && sk.top().l >= 4;) { sk.top().l -= 4; if (sk.top().l == 0) { node now = sk.top(); sk.pop(); if (!sk.empty() && sk.top().v == now.v)sk.top().l += now.l; } } }
void Printf() { int ans = 0; for (;!sk.empty();) { ans += sk.top().l; sk.pop(); } cout << ans; }
void Scanf() { cin >> n; for (int i = 1;i <= n;i++) { cin >> a[i]; } }
signed main() { Scanf(); for (int i = 1;i <= n;i++) { if (sk.empty() || sk.top().v != a[i]) { sk.push({ a[i],1 }); } else { sk.top().l++; } asd(); }Printf(); return 0; }
|