比赛地址c++
题目连接
⭐数组
题目:
给出一个01串,如今要求求得另外一个相同长度01串,使得两个串相加(容许为2),去除连续相同子序列后的三进制数最大spa
解析:
首先长度优先级确定大于高位数字大小的优先级,因此要保证不被去除任何连续相同子序列的状况下,让高位数尽量地大,因而能够考虑贪心的加1(即若是和上一位相加的结果相同则加0)code
#include<bits/stdc++.h> using namespace std; char str[100005]; int main() { int T, n; scanf("%d", &T); while (T--) { scanf("%d%s", &n, str + 1); char last = 0; for (int i = 1; str[i]; ++i) { char t = '1'; if (str[i] + t == str[i - 1] + last) --t; printf("%c", last = t); } printf("\n"); } }
题目连接
⭐get
题目:
给出一个\(d\),找出最小的天然数\(x\)知足,\(x\)至少含有4个因子(包括1和自己)且\(x\)的全部因子之差大于等于\(d\)it
解析:ast
#include<bits/stdc++.h> using namespace std; /*===========================================*/ const int maxn = 5e4; int prime[maxn]; bool vis[maxn]; int cnt; void euler(){ for (int i = 2; i < maxn; ++i){ if (!vis[i]) prime[cnt++] = i; for (int j = 0; j < cnt && prime[j] * i < maxn; ++j){ vis[i * prime[j]] = true; if (i % prime[j] == 0) break; } } } int main(){ euler(); int T, n; scanf("%d", &T); while (T--){ scanf("%d", &n); int* a = lower_bound(prime, prime + cnt, 1 + n); int* b = lower_bound(a + 1, prime + cnt, *a + n); printf("%lld\n", (LL)(*a) * (*b)); } }
题目连接
⭐⭐class
题目:
给出\(2n\)个数,初始能够指定任意的数做为基数,而后将数组中和为基数的两个数删除,较大的数做为新的基数,问如此往复是否能够删除全部的数,并输出每轮的基数test
解析:im
注意:
#include<bits/stdc++.h> using namespace std; /*===========================================*/ const int maxn = 2005; const int M = 1e6 + 5; int dat[maxn]; multiset<int, greater<int>> s; vector<pair<int, int>> ans; int n, T; int main() { scanf("%d", &T); while (T--) { scanf("%d", &n); for (int i = 1; i <= 2 * n; ++i) scanf("%d", &dat[i]); sort(dat + 1, dat + 2 * n + 1); for (int i = 1; i < 2 * n; ++i) { ans.clear(); s.clear(); int last = dat[2 * n]; ans.push_back(pair<int, int>(dat[2 * n], dat[i])); for (int j = 1; j < 2 * n; ++j) if (j != i) s.insert(dat[j]); while (!s.empty()) { multiset<int, greater<int>>::iterator t; int tmp = *s.begin(); s.erase(s.begin()); if ((t = s.find(last - tmp)) != s.end()) { ans.push_back(pair<int, int>(tmp, *t)); last = tmp; s.erase(t); } else break; } if (ans.size() == n) break; } if (ans.size() == n) { printf("YES\n%d\n", ans[0].first + ans[0].second); for (auto& i : ans) printf("%d %d\n", i.first, i.second); } else printf("NO\n"); } }
题目连接
⭐⭐⭐
题目:
给出一组数,相邻的数值\(a,b\)能够减去\(\min(a,b)\),这个操做能够进行任意次,同时还能够在操做前交换一次相邻的数值,问是否能够将这组数清空?
解析:
注意:在 0 与 n+1 的位置赋了 0 避免特判处理
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<b;++i) #define rep1(i,a,b) for(int i=a;i<=b;++i) #define rrep(i,a,b) for(int i=b-1;i>=a;--i) #define rrep1(i,a,b) for(int i=b;i>=a;--i) typedef long long LL; using namespace std; /*===========================================*/ const int maxn = 2e5 + 5; int dat[maxn]; int pre[maxn], suf[maxn]; bool check(int i) { return dat[i - 1] >= pre[i - 2] && dat[i] >= suf[i + 1] && dat[i - 1] - pre[i - 2] == dat[i] - suf[i + 1]; } int main() { int T; scanf("%d", &T); while (T--) { int n; scanf("%d", &n); rep1(i, 1, n) { scanf("%d", &dat[i]); if (pre[i - 1] < 0 || dat[i] < pre[i - 1]) pre[i] = -1; else pre[i] = dat[i] - pre[i - 1]; } suf[n + 1] = 0; rrep1(i, 1, n) if (suf[i + 1] < 0 || dat[i] < suf[i + 1]) suf[i] = -1; else suf[i] = dat[i] - suf[i + 1]; bool ok = false; rep1(i, 2, n) { if (pre[i - 2] == -1 || suf[i + 1] == -1) continue; if (ok = check(i)) break; swap(dat[i - 1], dat[i]); if (ok = check(i)) break; swap(dat[i - 1], dat[i]); } printf("%s\n", ok ? "YES" : "NO"); } }
题目连接
⭐⭐⭐
题目:
给出一个长度\(n\),给出操做\((i,j),p[j]=i\Rightarrow swap(i,j)\),但要付出\((i-j)^2\)的代价,现须要求出对应的长度为\(n\)的排列可能拥有的最大代价、排列自己以及中间的操做过程
解析:
注意:
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<b;++i) #define rep1(i,a,b) for(int i=a;i<=b;++i) #define rrep(i,a,b) for(int i=b-1;i>=a;--i) #define rrep1(i,a,b) for(int i=b;i>=a;--i) typedef long long LL; using namespace std; /*===========================================*/ const int maxn = 1e5 + 5; LL sum[maxn]; int main() { rep(i, 1, maxn) sum[i] = sum[i - 1] + 1LL * i * i; int T; scanf("%d", &T); while (T--) { long long n; scanf("%lld", &n); long long t = n / 2; if (n == 2) printf("1\n2 1\n1\n2 1\n"); else if (n == 3) printf("5\n2 3 1\n2\n2 1\n1 3\n"); else { printf("%lld\n", (n - 1) * (n - 1) + 2 * (sum[n - 2] - sum[n - 1 - t]) + (n & 1 ? (n - 1 - t) * (n - 1 - t) : 0)); printf("%lld", n - 1); rep(i, 2, t) printf(" %d", i + 1); printf(" 1 %lld", n); rep(i, t + 2, n) printf(" %d", i - 1); printf(" 2\n"); printf("%lld\n", n - 1); rep1(i, 2, t) printf("%d %lld\n", i, n); rrep(i, t + 1, n) printf("%d 1\n", i); printf("%lld 1\n", n); } } }