比赛地址c++
题目连接
⭐数组
题目:
每次能够倒入1份药剂/水,请问最少多少spa
解析:
直接对浓度进行进行最简约分,输出分母便可code
#include<bits/stdc++.h> using namespace std; int gcd(int a, int b) { return b ? gcd(b, a % b) : a; } int main() { int T, n; scanf("%d", &T); while (T--) { scanf("%d", &n); printf("%d\n", 100 / gcd(100, n)); } }
题目连接
⭐排序
题目:
给出\(1\sim n\)的排序,每次能够对子连续序列进行排序吗,问最多进行多少次操做之后可使得数列有序get
解析:
考虑到每次对\(n-1\)个序列进行排序的状况下(假设是对前\(n-1\)个数进行排序),若是\(1\)不在第\(n\)个位置,则下一次对后\(n-1\)个元素进行排序便可,同理若是\(n\)不在第1个位置,对后\(n-1\)个序列也能够达到相同的目的。可是当1在第\(n\)个位置且\(n\)在第\(1\)个位置时,必须先将\(1\)或\(n\)先置换出来,再进行如上步骤数学
#include<bits/stdc++.h> using namespace std; const int maxn = 55; int dat[maxn]; int main() { int T, n; scanf("%d", &T); while (T--) { scanf("%d", &n); bool ok = true; for (int i = 0; i < n; ++i) { scanf("%d", &dat[i]); if (i && dat[i] < dat[i - 1]) ok = false; } if (ok) printf("0\n"); else { if (dat[0] == n && dat[n - 1] == 1) printf("3\n"); else if (dat[0] == 1 || dat[n - 1] == n) printf("1\n"); else printf("2\n"); } } }
题目连接
⭐⭐⭐it
题目:
在一个X轴区间[0,m]上,给出\(n\)个机器人的初始朝向以及位置,机器人在整数点相遇时会碰撞,两机器人均会消失,已知机器人每一个单位时间行进一个单位长度,碰到区间端点时会反向前行,求出每一个机器人撞毁的时间class
解析:test
#include<bits/stdc++.h> using namespace std; struct TT { int pos, id; bool dir; }; stack<TT> s; vector<TT> v[2]; const int maxn = 3e5 + 5; int pos[maxn], n, m; void solve(vector<TT>& v) { sort(v.begin(), v.end(), [](TT i, TT j) {return i.pos < j.pos; }); for (auto& i : v) { if (i.dir) s.push(i); else { if (!s.empty()) { auto t = s.top(); s.pop(); pos[i.id] = pos[t.id] = (i.pos - t.pos) / 2; } else s.push(TT{ -i.pos,i.id,1 }); } } while (s.size() > 1) { auto t1 = s.top(); s.pop(); auto t2 = s.top(); s.pop(); pos[t1.id] = pos[t2.id] = (2 * m - t1.pos - t2.pos) / 2; } if (!s.empty()) { pos[s.top().id] = -1; s.pop(); } } int main() { int T; char ch; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); v[0].clear(), v[1].clear(); for (int i = 0; i < n; ++i) scanf("%d", &pos[i]); for (int i = 0; i < n; ++i) { scanf(" %c", &ch); v[pos[i] & 1].push_back(TT{ pos[i],i, ch == 'R' }); } solve(v[1]), solve(v[0]); for (int i = 0; i < n; ++i) printf("%d ", pos[i]); printf("\n"); } }
题目连接
⭐⭐⭐
题目:
假设\(n\)个位置上至多有\(\lfloor\frac{n}{2}\rfloor\)上坐了人,用\(1\)表示,空座位用\(0\)表示,第\(i\)我的若是想要移动到第\(j\)个位置,则须要付出\(\mid i-j\mid\)的代价,现需另全部人不在原被占有位的最小代价
解析:
注意:
引理的做用主要用于进行迭代更新\(dp\)数组时,对于第\(i\)个空位只须要迭代\(\min(人的个数,i)\)
若是缺乏引理,对结果其实没有影响,可是状态的定义会变得较为复杂与难以理解,较难寻找到正确的状态转移方程
#include<bits/stdc++.h> using namespace std; const int maxn = 5e3 + 5; int p[maxn]; vector<int> n1(1), n2(1); int dp[maxn][maxn]; int main() { int n; scanf("%d", &n); for (int i = 0; i < n; ++i) { scanf("%d", &p[i]); if (p[i]) n2.push_back(i); else n1.push_back(i); } for (int i = 0; i < n1.size(); ++i) for (int j = i + 1; j < n2.size(); ++j) dp[i][j] = 0x3f3f3f3f; for (int i = 1; i < n1.size(); ++i) for (int j = 1; j <= min(int(n2.size() - 1), i); ++j) dp[i][j] = min(dp[i - 1][j], dp[i - 1][j - 1] + abs(n1[i] - n2[j])); printf("%d", n2.size() == 1 ? 0 : dp[n1.size() - 1][n2.size() - 1]); }
题目连接
⭐⭐⭐⭐
题目:
给出\(n\)个城市以及\(m\)块区域,以及每座城市距离每块区域之间的距离,能够在第\(i(1\sim n)\)轮在某个城市内安插一个控制装置,可以掌控距离该城市距离在\(i\)之内的城池,问掌控城池的指望,答案模取\(998244353\)
解析:
#include<bits/stdc++.h> using namespace std; int d[25][50005]; typedef long long ll; const ll mod = 998244353; int cnt[25]; ll q_pow(ll x, ll n) { ll ans = 1; while (n) { if (n & 1) ans = ans * x % mod; n >>= 1; x = x * x % mod; } return ans; } int main() { int n, m; scanf("%d%d", &n, &m); for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) scanf("%d", &d[i][j]); ll inv = 1; for (int i = 2; i <= n; ++i) inv = inv * i % mod; inv = q_pow(inv, mod - 2); ll ans = 0; for (int j = 0; j < m; ++j) { memset(cnt, 0, sizeof(cnt)); for (int i = 0; i < n; ++i) ++cnt[d[i][j]]; ll ret = 1, now = 0; for (int i = n; i >= 1; --i) { now += cnt[i + 1]; ret = ret * now % mod; if (now-- == 0) break; } ans = ((ans + 1 - ret * inv % mod) % mod + mod) % mod; } printf("%lld", ans); }