Educational Codeforces Round 81 (Div. 2)
比赛链接:https://codeforces.com/contest/1295
A - Display The Number
题意
输出按照电子钟表的格式用 n 段能组成的最大值。(1≤n≤105)
思路
每两段组成 1 增加位长,如有余与数首的 1 组成 7。
代码
#include <bits/stdc++.h> using namespace std; void solve() { int n; cin >> n; if (n & 1) cout << '7' << string((n - 3) / 2, '1') << "\n"; else cout << string(n / 2, '1') << "\n"; } int main() { int t; cin >> t; while (t--) solve(); }
B - Infinite Prefixes
题意
一个 01 串可以无限串连,问 01 个数之差为 x 的前缀有多少个(考虑空串)。(1≤|s|≤105,10-9≤x≤109)
思路
递推一遍记录每个位置 01 个数的差,串尾的差还表示下一串与上一串的每个位置差的变化情况。
无限的情况是串尾之差为 0,且串中有 x。
否则记录所有最终可以变化为 x 的位置个数,判定条件:同正负,与 x 之差可以整除串尾的差。
代码
#include <bits/stdc++.h> using namespace std; void solve() { int n, x; cin >> n >> x; string s; cin >> s; int cnt[n] = {}; for (int i = 0; i < n; i++) { if (i != 0) cnt[i] = cnt[i - 1]; if (s[i] == '0') ++cnt[i]; else --cnt[i]; } if (cnt[n - 1] == 0) cout << (count(cnt, cnt + n, x) ? -1 : 0) << "\n"; else { set<int> st; for (int i : cnt) { if (1LL * (x - i) * cnt[n - 1] >= 0 and (x - i) % cnt[n - 1] == 0) { st.insert(i); } } map<int, int> Map; for (int i : cnt) ++Map[i]; int ans = 0; for (int i : st) { ans += Map[i]; } cout << ans + (x == 0) << "\n"; } } int main() { int t; cin >> t; while (t--) solve(); }
C - Obtain The String
题意
利用字符串 s 的子序列串连成字符串 t,问最少需要用多少个子序列。(1≤|s|≤105,1≤|t|≤105)
思路
贪心,记录字符串 s 中每个字符的位置,遍历字符串 t,每次二分查找大于当前位置的字符位置。
代码
#include <bits/stdc++.h> using namespace std; void solve() { string s, t; cin >> s >> t; vector<int> v[26]; for (int i = 0; i < s.size(); i++) { v[s[i] - 'a'].push_back(i); } int ans = 1, pos = -1; for (int i = 0; i < t.size(); i++) { int id = t[i] - 'a'; if (v[id].size() == 0) { cout << "-1" << "\n"; return; } else { auto it = upper_bound(v[id].begin(), v[id].end(), pos); if (it != v[id].end()) { pos = *it; } else { pos = v[id][0]; ++ans; } } } cout << ans << "\n"; } int main() { int t; cin >> t; while (t--) solve(); }
D - Same GCDs
题意
给定 a,m,计算 [0,m) 内满足 gcd(a,m)=gcd(a+x,m) 的 x 个数。(1≤a<m≤1010)
思路
设 gcd(a,m)=d,所求即满足 gcd(a/d,m/d)=gcd((a+x)/d,m/d)=1 的 x 的个数,即欧拉函数 phi(m/d) 。
代码
#include <bits/stdc++.h> using LL = long long; using namespace std; LL phi(LL n) { LL ret = n; for (LL i = 2; i * i <= n; i++) { if (n % i == 0) { ret = ret / i * (i - 1); while (n % i == 0) n /= i; } } if (n > 1) ret = ret / n * (n - 1); return ret; } void solve() { LL a, m; cin >> a >> m; cout << phi(m / __gcd(a, m)) << "\n"; } int main() { int t; cin >> t; while (t--) solve(); }