A. New World, New Me, New Array
贪心的想每次都赋值一个$ p $ 如果正好和为 $ k $ 则答案就是 \(k/p\) ,否则是\(k/p+1\)。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;void solve() {int n, k, p;cin >> n >> k >> p;if (n * p < abs(k)) {cout << -1 << '\n';return;}int ans = abs(k / p);if (k % p != 0) ans++;cout << ans << '\n';
}signed main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t--)solve();
}
B. Having Been a Treasurer in the Past, I Help Goblins Deceive
简单地想,\(O(n)\) 扫描一遍记录前后各放多少个 "-" 会使子序列最多,直接计算即可。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;void solve() {string s;int n;cin >> n;cin >> s;int cnt = 0, cnt1 = 0;for (auto t : s) {if (t == '-') cnt++;}int mx = 0;cnt1 = s.size() - cnt;for (int i = 1; i <= cnt; i++) {int x = i, y = cnt - i;mx = max(mx, x * y);}cout << mx*cnt1 << '\n';
}signed main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t--)solve();
}
C. Creating Keys for StORages Has Become My Main Skill
贪心 ,\([0,n-1]\) 尽可能取,维护或值,如果恰好为 \(x\) 则是答案。否则尽可能修改大的将最后一项取为 \(x\),这样 \(MEX\) 最大。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;void solve() {int n, x;cin >> n >> x;int now = 0;vector<int> ans(n+10, 0);for (int i = 1; i < n; i ++ ) {if ((x | i) == x) {ans[i] = i;now |= i;}}if (now != x) {ans[n - 1] = x;}for (int i = 0; i < n; i ++ ) {cout << ans[i] << ' ';}cout << '\n';
}signed main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t--)solve();
}
D. For Wizards, the Exam Is Easy, but I Couldn't Handle It
很明显反转数的个数变化只与选择的区间有关,与区间外的数无关,区间的贡献则是区间中小于 \(l\) 的个数减去大于 \(l\) 的个数 。
\(n^2\) 暴力枚举,在过程中记下 \([l,r]\) 区间中大于 \(l\) 和小于 \(l\) 的个数,然后统计贡献最大的区间便是答案。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;void solve() {int n;cin >> n;vector<int> a(n + 1);for (int i = 1; i <= n; i++) {cin >> a[i];}int ans = 0;pair<int, int> anss;for (int l = 1; l <= n; l++) {int x = 0, y = 0;for (int r = l; r <= n; r++) {if (a[r] > a[l]) x++;if (a[r] < a[l]) y++;if (y - x >= ans) {ans = y - x;anss.first = l, anss.second = r;}}}cout << anss.first << ' ' << anss.second << '\n';
}signed main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t--)solve();
}
E. Do You Love Your Hero and His Two-Hit Multi-Target Attacks?
大致题意:Akito需要在坐标系中放置$ n $ 根法杖,且这些法杖的位置必须是不同的整数坐标点。放置后,恰好有$ k $ 对法杖位于同一条水平线或垂直线上。
构造题,利用组合数的知识 \(C(x,2)\) 尽可能构造即可。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;void solve() {int n;cin >> n;if (n == 0) {cout << "2\n0 0\n1 1\n";return;}vector<pair<int, int>> ans;int yu = n;int ls = 1, d = 0;while (yu > 2) {for (int i = 2; i <= 500; i++) {int x = (i - 1) * i / 2;if (x > yu) {int res = (i - 1) * (i - 2);yu -= res / 2;for (int j = ls; j <= ls + i - 1 - 1; j++) {ans.push_back({-j, d});}ls = ls + i - 1;d -= 1;break;}}}if (yu == 2) {ans.push_back({1, 1});ans.push_back({2, 1});ans.push_back({3, 2});ans.push_back({4, 2});} else if (yu == 1) {ans.push_back({1, 1});ans.push_back({2, 1});}cout << ans.size() << '\n';for (pair<int, int> p : ans) {cout << p.first << ' ' << p.second << '\n';}
}signed main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t--)solve();
}
F. Goodbye, Banker Life
打表找一下规律可以发现第 $ n $ 行是由最近的第 $ n-2^x $ 行转移过来的,那么很明显可以递归,通过递归记录一下答案,处理一下直接输出。代码实现比较抽象,具体看代码。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;
int n, x;
int ksm(int x, int y) {int ans = 1;while (y) {if (y & 1)ans = ans * x;y >>= 1;x = x * x;}return ans;
}
vector<int> po;
void init() {for (int i = 32; i >= 0; i--) {int x = ksm(2, i);po.push_back(x);}
}
deque<pair<string, int>> de;
void dfs(int u) {if (u == 1 || (u & (u - 1)) == 0) {if (u == 1) {de.push_front({"1", 1});} else {de.push_back({"1", u});}return;}for (int i = 0; i < 32; i++) {if (po[i] <= u) {dfs(u - po[i]);int yu = u - 2 * (u - po[i]);de.push_back({"0", yu});de.push_back({"x", 0});return;}}
}
void pr();
void pr1(int l, int r);
void pr0(int l, int r);
void solve() {while (de.size()) de.pop_front();cin >> n >> x;string s = to_string(1);for (int i = 0; i < 32; i++) {if (n == po[i]) {pr();return;}}dfs(n);vector<pair<string, int>> p;while (de.size()) {pair<string, int> it = de.front();de.pop_front();p.push_back(it);}for (int i = 0; i < p.size(); i++) {string a = p[i].first;int b = p[i].second;if (a == "0") {pr0(1, b);} else if (a == "1") {pr1(1, b);} else if (a == "x") {int len = 0;if (p[i - 1].first == "0") len = i - 1;else len = i;string lp = "";for (int j = 0; j < len; j++) {int cnt = p[j].second;if (p[j].first == "0")for (int k = 1; k <= cnt; k++) {cout << 0 << ' ';lp += "0";} else if (p[j].first == "1") {for (int k = 1; k <= cnt; k++) {cout << x << ' ';lp += "1";}} elsefor (char t : p[j].first) {if (t == '1') cout << x << ' ', lp += "1";else if (t == '0') cout << 0 << ' ', lp += "0";}}p[i].first = lp;}}cout << '\n';
}
void pr() {for (int i = 1; i <= n; i++)cout << x << ' ';cout << '\n';
}
void pr1(int l, int r) {for (int i = l; i <= r; i++) cout << x << ' ';
}
void pr0(int l, int r) {for (int i = l; i <= r; i++) cout << 0 << ' ';
}signed main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int t = 1;init();cin >> t;while (t--)solve();
}
/*
第 1 行: 1
第 2 行: 1 1
第 3 行: 1 0 1
第 4 行: 1 1 1 1
第 5 行: 1 0 0 0 1
第 6 行: 1 1 0 0 1 1
第 7 行: 1 0 1 0 1 0 1
第 8 行: 1 1 1 1 1 1 1 1
第 9 行: 1 0 0 0 0 0 0 0 1
第 10行: 1 1 0 0 0 0 0 0 1 1
*/