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