比賽地址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"); } }