比赛地址c++
题目连接
⭐数组
题目:
定义一个数\(x\)若为 interesting 则\(x\)各数位加起来的和大于\(x+1\)各数位加起来的和,现给出\(n\),问\(1\sim n\)之间有多少个 interesting 的数spa
解析:
只有个位数为9的时候才会知足题意,那也就是求得有多少个以9结尾的数字便可rest
#include<bits/stdc++.h> using namespace std; int main() { int T, n; scanf("%d",&T); while (T--) { scanf("%d", &n); printf("%d\n", n / 10 + (n % 10 == 9)); } }
题目连接
⭐⭐code
题目:
给出一个字符串\(s\),能够从任意下标开始,先向右移动(能够不动)再向左移动(能够不动),问是否存在移动过程当中通过的字符轨迹为字符串\(t\)递归
解析:字符串
题目连接
⭐get
题目:
给出一个点球大战的结果,0 表明未进, 1 表明进球, ? 表明未知,问判断一方得到胜利至少要踢多少次点球it
解析:
以判断A方胜利为例,则理想状况是当前第\(x\)轮踢球后,小于\(x\)的A方未知(?)的进球全为命中,而B方全不命中的状况下,即便A方后续一个球也踢不进,B方所有命中,也没法追平比分,那也就是暴力判断一下\(1\sim 10\)的轮数是否能够结束比赛class
#include<bits/stdc++.h> using namespace std; char s[15]; int main() { int T; scanf("%d", &T); while (T--) { scanf("%s", s + 1); int t[2] = { 0 }; int c[2] = { 0 }; int i; for (i = 1; s[i]; ++i) { if (s[i] == '?') ++t[i & 1]; else if (s[i] == '1') ++c[i & 1]; if (c[0] + t[0] > (10 - i) / 2 + c[1] || c[1] + t[1] > (11 - i) / 2 + c[0]) break; } printf("%d\n", min(i, 10)); } }
题目连接
⭐⭐
题目:
如今给出一个字符串\(s\),问是否能够将串中键入某字符的操做更改成使用 Backspace(退格键),使得字符串变为\(t\)
解析:
#include<bits/stdc++.h> using namespace std; const int maxn = 1e5 + 5; char s[maxn], t[maxn]; int main() { int T; scanf("%d", &T); while (T--) { scanf("%s%s", s, t); int i = strlen(s) - 1, j = strlen(t) - 1; while (j >= 0 && i >= 0) { if (s[i] == t[j]) --j, --i; else i -= 2; } printf("%s\n", j >= 0 ? "NO" : "YES"); } }
题目连接
⭐⭐⭐
题目:
对\([1,2,3,\dots]\)的序列,能够对他进行两种操做
如今给出\(n,m,\)结果序列,问有多少个知足条件的\(k\)能够经过数值交换获得结果序列,并增序输出\(k\)
解析:
引理: 对于一个长度位\(n\)排列\(a\)和排列\(b\),让\(a=b\)的最小交换次数是\(n\)与将\(a[i]\)与\(b[i]\)链接后,数组长度与对应的图中环数的差
证实: 对于无向图中任意一个环,假如环中点的数量为\(c\),则当\(c-1\)个数位置都正确之后,剩下的数位置也正确,并且环内每次交换操做(除了最后一次)至多可使得1个数回归原位,故每一个环均可以少进行1次交换
考虑到\(m\)次数值交换,最多使得\(2m\)个数与原数列位置不一样(每次选择未选过的两个数),那考虑记录结果数列\(p\)中每一个数,对 "相对于\([1,2,3,\dots]\)的偏移量" 所做出的贡献,那若是这个数\(cnt+2*m\ge n\),那就是有可能在交换次数小于等于\(m\)时实现的,这样的粗略断定的基础上再用引理进行\(O(n)\)的准确破案顶。另外经过\(m\)的范围能够计算出,能经过粗略断定的数不超过3个
#include<bits/stdc++.h> using namespace std; const int maxn = 3e5 + 5; int p[maxn]; int cnt[maxn]; bool vis[maxn]; vector<int> v; int n, m; bool check(int k) { v.clear(); for (int i = k; i < n; ++i) v.push_back(p[i]); for (int i = 0; i < k; ++i) v.push_back(p[i]); int t = n; memset(vis, 0, sizeof(vis)); for (int i = 0; i < n; ++i) { if (vis[i]) continue; int j = i; while (!vis[j]) vis[j] = true, j = v[j]; --t; } return t <= m; } int main() { int T; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); for (int i = 0; i < n; ++i) { scanf("%d", p + i); --p[i]; ++cnt[(i - p[i] + n) % n]; } vector<int> ans; for (int i = 0; i < n; ++i) if (cnt[i] + 2 * m >= n && check(i)) ans.push_back(i); printf("%d ", ans.size()); for (auto& i : ans) printf("%d ", i); printf("\n"); } }