A题: Divisible
难度在于打开题目
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
typedef pair<int, int> PII;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n, k;
cin >> n >> k;
for (int i = 1; i <= n; i ++ ) {
int x; cin >> x;
if (x % k == 0) {
cout << x / k << ' ';
}
}
return 0;
}
B题: Substring
长度它告诉你最大是100
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
typedef pair<int, int> PII;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
string s; cin >> s;
set<string> st;
int n = s.size();
s = " " + s;
for (int i = 1; i <= n; i ++ ) {
for (int j = 1; j + i <= n + 1; j ++) {
string t = s.substr(j, i);
st.insert(t);
}
}
cout << st.size() << endl;
return 0;
}
C题: Ideal Holidays
第一步:压缩给出来的数的区间到 1 ~ a + b
第二步:进行判断
设holiday为1
对应一周 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1
因为我们已经压缩过区间了,所以输出Yes的情况只能是
1.全在前面那部分 1 中
2.一部分在前,一部分在后面的 1 中
如下面代码所示
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
typedef pair<int, int> PII;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
ll n, a, b; cin >> n >> a >> b;
vector<int> v(n);
for (int i = 0; i < n; i ++ ) {
cin >> v[i];
v[i] %= (a + b);
if (v[i] == 0) v[i] = a + b;
}
sort(v.begin(), v.end());
bool ok = false;
if (v[n - 1] - (v[0] - 1) <= a) ok = true;
for (int i = 1; i < n; i ++ ) {
if (v[i] - v[i - 1] > b && v[i - 1] <= a) ok = true;
}
if (ok) cout << "Yes\n";
else cout << "No\n";
return 0;
}
D题: Popcount and XOR
贪心。要满足异或起来为 c, 那么要在 c 二进制下为 1 的位置 a 和 b一个为 0, 一个为 1。
所以我们要尽可能的保持a = b,因为在考虑完 c 后,其他位置要异或起来为0的,这
意味着a与b要两者都是1或者0。
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
typedef pair<int, int> PII;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int a, b; ll c;
cin >> a >> b >> c;
ll l = 0, r = 0;
for (int i = 0; i < 60; i ++ ) {
if (c >> i & 1) {
if (a >= b) l += (1ll << i), a --;
else r += (1ll << i), b --;
if (a < 0 || b < 0) return cout << -1 << endl, 0;
}
}
if (a != b) cout << -1 << endl;
else {
for (int i = 0; i < 60; i ++ ) {
if (!(c >> i & 1) && a) {
l += (1ll << i), r += (1ll << i);
a --;
}
}
if (a != 0) cout << -1 << endl;
else cout << l << ' ' << r << endl;
}
return 0;
}
E题: Set Add Query
1 3 3 2
1生效的区间在 [1,4]
2生效的区间在 [4,4]
3生效的区间在 [2,2]
自然想到前缀和进行处理
如果这个数在之前没有出现过,那么将其放进 id 中
否则就进行处理,比如 1 3 2 4 3 轮到第 2 个 3 时,那么 ans[3]就要加上 cnt[i - 1] - cnt[id - 1]
最后再把还剩在 id 里面的处理掉即可。
#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, q; cin >> n >> q;
map<int, int> id;
vector<ll> cnt(q + 1);
vector<ll> ans(n + 1);
for (int i = 1; i <= q; i ++ ) {
int x; cin >> x;
if (id[x]) {
ans[x] += cnt[i - 1] - cnt[id[x] - 1];
id.erase(x);
}else {
id[x] = i;
}
cnt[i] = id.size();
cnt[i] += cnt[i - 1];
}
for (auto t : id) {
ans[t.first] += cnt[q] - cnt[t.second - 1];
}
for (int i = 1; i <= n; i ++ ) cout << ans[i] << ' ';
return 0;
}