比賽地址c++
題目連接
⭐spa
題目:
有兩個計票員,\(n\)個觀衆,每一個觀衆能夠按順序投票,以下所示有三種票code
解析:
讓一個計票員專門收反對票,另外一個計票員收其餘種類的票,很顯然答案就是\(1\)與\(3\)的票數之和隊列
#include<bits/stdc++.h> using namespace std; /*===========================================*/ int main() { //FRE; int T, n, t; scanf("%d", &T); while (T--) { scanf("%d", &n); int t1 = 0, t2 = 0; while (n--) { scanf("%d", &t); if (t & 1) ++t1; else ++t2; } printf("%d\n", t1); } }
題目連接
⭐ci
題目:
給出\(a,b,c\)表明\(A,B,C\)三個數所表明的十進制位數,同時知足\(GCD(A,B)=C\),輸出知足條件的\(A,B\)字符串
解析:
因爲\(A=A'C,B=B'C\)且\(A'\)與\(B'\)互質,考慮C爲10的冪,能夠很好的控制A與B的位數,那麼任務就轉變成了尋找位數分別爲\(a-c+1\)與\(b-c+1\)且互質的\(A'\)與\(B'\),不難發現\(10^x與10^y+1\)必定互質(因爲前者只能質因數分解成若干個2與5的冪次,然後者必定不能被2或5整除),那麼問題迎刃而解get
#include<bits/stdc++.h> typedef long long ll; using namespace std; /*===========================================*/ ll ten[10]; int main() { //FRE; int T; ten[1] = 1; for (int i = 2; i < 10; ++i) ten[i] = ten[i - 1] * 10; scanf("%d", &T); int a, b, c; while (T--) { scanf("%d%d%d", &a, &b, &c); printf("%lld %lld\n", ten[a - c + 1] * ten[c], (ten[b - c + 1] + 1) * ten[c]); } }
題目連接
⭐⭐數學
題目:
給出一疊牌,從上到下給出每一個牌的顏色,有\(m\)次詢問,每次詢問最上方顏色爲\(t\)的牌的位置,輸出,並把這張牌抽出放於牌頂string
解析:
因爲每次每次詢問最上方的牌,並把它放在牌頂,因此只須要記錄每種顏色最上方的牌,並在每次查詢時,維護好這個顏色隊列便可it
#include<bits/stdc++.h> using namespace std; /*===========================================*/ const int maxn = 3e5 + 5; int q[maxn]; int cnt = 0; bool vis[maxn]; int pos[maxn]; int main() { //FRE; int n, m, t; scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) { scanf("%d", &t); if (!vis[t]) { vis[t] = true; q[cnt++] = t; pos[t] = i; } } while (m--) { scanf("%d", &t); printf("%d ", pos[t]); int i = 0; for (; q[i] != t; ++i) ++pos[q[i]]; for (; i > 0; --i) q[i] = q[i - 1]; pos[t] = 1; q[0] = t; } }
題目連接
⭐⭐
題目:
若是\(s_i=s_j(i<j)\),且\(s_{i+1}=s_{j+1}\),則花費加1,如今給出字符串長度,以及字符集大小,求出最小代價的字符串
解析:
能夠嘗試考慮重複構造代價爲0的串,即時刻保證當前兩位後綴從未在以前出現過,能夠考慮這樣的構造方法,每次從\(a\)開始枚舉字符,先輸出一個\(cur\),再輸出\(cur\#\),\(cur\)表明當前字符,\(\#\)表明比\(cur\)大的字符,這樣能夠保證全部字符集合中全部兩兩組合都出現過
#include<bits/stdc++.h> using namespace std; /*===========================================*/ int n, m, c; void P(int i) { printf("%c", i + 'a'); if (++c == n) exit(0); } int main() { //FRE; scanf("%d%d", &n, &m); while (1) { for (int i = 0; i < m; ++i) { P(i); for (int j = i + 1; j < m; ++j) P(i), P(j); } } }
題目連接
⭐⭐⭐⭐
題目:
給出一個矩陣,\(o\)表明白塊,\(*\)表明黑塊,每一個白塊能夠染成red與blue兩種顏色,橫排兩個連續的紅塊能夠防止一個多米諾牌,豎排兩個連續的藍塊能夠放置一個多米諾牌,多米諾牌不能重疊,每一個白塊必須被染色,問每種染色方案所能放置的最大多米諾牌數之和(取模\(998244353\))
解析:
考慮對於某一行連續的白塊,定義\(dp[i]\)爲前\(i\)個連續白塊最多能放置的多米諾牌之和,那麼對於\(dp[i+1]\)
綜上能夠獲得狀態轉移方程\(dp[i]=dp[i-1]+2*dp[i-2]+2^{i-2}\)
那麼統計全部連續的白塊行和白塊列,利用\(dp\)能夠\(O(1)\)求出這段白塊行/列對於每種染色矩陣的貢獻,所以假設這段白塊長度爲\(x\),答案加上\(dp[x]*2^{white-x}\)
#include<bits/stdc++.h> typedef long long ll; using namespace std; /*===========================================*/ using namespace std; const int maxn = 3e5 + 5, mod = 998244353.; ll dp[maxn], two[maxn]; string e[maxn]; int main() { IOS two[0] = 1; int n, m; for (int i = 1; i < maxn; ++i) two[i] = two[i - 1] * 2 % mod; for (int i = 2; i < maxn; ++i) dp[i] = (dp[i - 1] + 2 * dp[i - 2] % mod + two[i - 2]) % mod; cin >> n >> m; int end = max(n, m); ll ret = 0, c; int white = 0; for (int i = 0; i < n; ++i) { cin >> e[i]; for (auto& j : e[i]) white += j == 'o'; } for (int i = 0; i < n; ++i) { c = 0; for (int j = 0; j < m; ++j) { if (e[i][j] == 'o') ++c; else if (c) { ret = (ret + dp[c] * two[white - c]) % mod; c = 0; } } if (c) ret = (ret + dp[c] * two[white - c]) % mod; } for (int j = 0; j < m; ++j) { c = 0; for (int i = 0; i < n; ++i) { if (e[i][j] == 'o') ++c; else if (c) { ret = (ret + dp[c] * two[white - c]) % mod; c = 0; } } if (c) ret = (ret + dp[c] * two[white - c]) % mod; } cout << ret; }