我要开始打Codeforces了,这是我的第三场比赛,本来以为可以快速上分的,谁知在pupil的路上越走越远。
本场战绩: Cost Time: 2 hours Solved: 1.5 Rank: 3023 Rating: -31
A. Forgetting Things 题目大意:输入小于10的正整数a和b,输出任意分别以a和b开头的两个连续整数,如果不存在这样的数,则输出"-1"。 解法:可以发现只有当 a a a等于 b b b,当 a + 1 a + 1 a+1等于 b b b以及当 a a a等于 9 9 9, b b b等于 1 1 1这三种情况下可以找到答案。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const int maxn = 2e5 +10; int a, b; /* * 省略了快读和快写 */ int main() { read(a) ,read(b); if (a == b) { cout << a * 10 + 1 << " " << b * 10 + 2 << endl; } else if (a + 1 == b) { cout << a * 10 + 9 << " " << b * 10 << endl; } else if(a == 9 && b == 1) { cout << a * 10 + 9 << " " << b * 100 << endl; } else { writeln(-1); } return 0; }B. TV Subscriptions 题目大意:有n天,每天电视台都播放着编号为 a i ( 1 ≤ a i ≤ k ) a_i(1 \leq a_i \leq k) ai(1≤ai≤k)的节目,现在要求至少要订阅多少个节目才能使连续 d d d天有节目看?
解法:用一个长度为 d d d的区间去扫描记录节目的数组,同时维护一个记录区间节目数的变量,扫描完即可得到最小的节目数。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const int maxn = 2e5 +10; const int N = 1e6 + 10; int T, n, k, d; int a[maxn], vis[N]; /* * 省略了快读和快写 */ int main() { read(T); while(T--) { read(n); read(k); read(d); for (int i = 1; i <= n; i++) { read(a[i]); vis[a[i]] = 0; } int ans = inf, t = 0; for (int i = 1; i <= d; i++) { if (!vis[a[i]]) t++; vis[a[i]]++; } ans = min(ans, t); for (int i = d + 1; i <= n; i++) { vis[a[i - d]]--; if (!vis[a[i - d]]) t--; if (!vis[a[i]]) t++; vis[a[i]]++; ans = min(ans, t); } writeln(ans); } return 0; }C. p-binary 题目大意:给定n和p的值,求出最小的k值,可以使得 n = ∑ i = 1 k ( 2 x i + p ) n= \sum^k_{i=1}(2^{x_i}+p) n=∑i=1k(2xi+p)成立。 解法:上式可转化为: n − k ∗ p = ∑ i = 1 k 2 x i n-k*p= \sum^k_{i=1}2^{x_i} n−k∗p=i=1∑k2xi 令 t = n − k ∗ p t=n-k*p t=n−k∗p,由二进制转十进制的“位权法”,我们可以想到考虑 t t t 的二进制表示。
当 t t t 的二进制数中1的个数大于 k k k 时, k k k 不符合条件。当 t t t 的二进制数中1的个数小于或等于 k k k 时,我们可以通过分解使得 2 x i 2^{x_i} 2xi 的个数等于 k k k。(比如 2 5 = 2 4 + x 4 2^5=2^4+x^4 25=24+x4)。于是,我们就可以从小到大遍历 k k k 的值,最先找到答案便是我们要找的。注意:当出现 t < k t < k t<k这种情况时,说明不存在满足条件的 k k k 值。
关于 k k k 的上限,由上述可知,当 c a l ( n − k ∗ p ) ≤ k cal(n-k*p) \leq k cal(n−k∗p)≤k 就会得到结果,而 n ≤ 1 0 9 , − 1000 ≤ p ≤ 1000 n \leq 10^9,-1000\leq p \leq 1000 n≤109,−1000≤p≤1000 ,所以 k k k 的值必定不会超过31。
/** * Author: Veggie */ #include <bits/stdc++.h> using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const int maxn = 2e5 +10; int a, b; /* * 省略了快读和快写 */ int cal(int x) { int cnt = 0; while (x) { if (x & 1) cnt ++; x >>= 1; } return cnt; } int main() { read(a), read(b); int t; for (int k = 1; k < 32; k++) { t = a - k * b; if (t < k) break; if (cal(t) <= k) { writeln(k); return 0; } } writeln(-1); return 0; }