比赛地址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; }