比賽地址c++
題目連接
⭐數組
題意:
給出一組序列,每次能夠將大於當前數組平均數的數刪去,問最多能夠刪去多少個數spa
解析:
很是顯然,因爲最小值會一直拉低平均值使得其一直小於最大值,因此只有最小值會被保留code
#include<bits/stdc++.h> using namespace std; int dat[10005]; int main() { int T, n; scanf("%d", &T); while (T--) { scanf("%d", &n); int mn=0x3f3f3f3f; for (int i = 0; i < n; ++i) scanf("%d", &dat[i]), mn=min(mn,dat[i]); int t = n; for (int i = 0; i < n; ++i) if (dat[i] == mn) --t; printf("%d\n", t); } }
題目連接
⭐get
題意:
定義數組\(b\)中任意兩元素的差的絕對值小於等於數組內的最大值,則稱這個數組是strange的。如今給出數組\(a\),求\(a\)的子序列構成strange數組的最大長度it
解析:class
#include<bits/stdc++.h> using namespace std; int dat[100005]; int main() { int T, n; scanf("%d", &T); while (T--) { scanf("%d", &n); for (int i = 0; i < n; ++i) scanf("%d", &dat[i]); sort(dat, dat + n); int i; int mn = INT32_MAX; int ans = 0; for (i = 0; i < n; ++i) { if (i) mn = min(mn, dat[i] - dat[i - 1]); if (dat[i] > mn) break; ++ans; } printf("%d\n", ans); } }
題目連接
⭐⭐test
題意:
給出一個樹,以及每一個節點之間的取值範圍,如今對每一個節點取某個值,使得相鄰節點值的差絕對值的和最大im
解析:統計
#include<bits/stdc++.h> using namespace std; const int maxn = 1e5 + 5; vector<int> e[maxn]; int l[maxn], r[maxn]; long long dp[maxn][2]; void dfs(int fa, int cur) { for (auto& i : e[cur]) { if (i == fa) continue; dfs(cur, i); dp[cur][0] += max(dp[i][0] + abs(l[cur] - l[i]), dp[i][1] + abs(l[cur] - r[i])); dp[cur][1] += max(dp[i][0] + abs(r[cur] - l[i]), dp[i][1] + abs(r[cur] - r[i])); } } int main() { int T, n,a,b; scanf("%d", &T); while (T--) { memset(dp, 0, sizeof(dp)); scanf("%d", &n); for (int i = 1; i <= n; ++i) { scanf("%d%d", &l[i], &r[i]); e[i].clear(); } for (int i = 1; i < n; ++i) scanf("%d%d", &a, &b), e[a].push_back(b), e[b].push_back(a); dfs(0, 1); printf("%lld\n", max(dp[1][0], dp[1][1])); } }
題目連接
⭐⭐⭐
題意:
在一個長度爲\(2n\)的軸上,選擇\(n\)個點對,保證任意兩個點對的距離都相等,或者一個點對被包含在另外一個點對中,詢問合法的有多少種點對選擇方式
解析:
#include<bits/stdc++.h> using namespace std; const int maxn = 1e6 + 5; long long dp[maxn]; const long long mod = 998244353; int main() { int n; scanf("%d", &n); for (int i = 1; i <= n; ++i) for (int j = 2 * i; j <= n; j += i) ++dp[j]; dp[0] = 1; for (int i = 1; i <= n; ++i) dp[i] = (2 * dp[i - 1] + dp[i]) % mod; printf("%lld", (dp[n] - dp[n - 1] + mod) % mod); }
題目連接
⭐⭐⭐⭐
題意:
給出兩個樹,找到最大的點集使得在一號樹中在點集內的全部點要求在一條鏈上,在二號樹中在點集內的任意兩個點不能一個點是另外一個點的祖宗
解析:
#include<bits/stdc++.h> using namespace std; const int maxn = 3e5 + 5; vector<int> e1[maxn], e2[maxn]; int l[maxn], r[maxn]; int cnt,ans; typedef pair<int, int> P; set<P> s; void dfs2(int cur) { l[cur] = ++cnt; for (auto& i : e2[cur]) dfs2(i); r[cur] = cnt; } int insert(int x) { auto i = s.lower_bound(P(l[x],x)); if (i != s.end() && r[i->second] <= r[x]) return 0; if (i == s.begin()) return -1; --i; int t = i->second; if (r[x] > r[t]) return -1; s.erase(i); return t; } void dfs1(int cur) { int res = insert(cur); if (res) s.insert(P(l[cur], cur)); ans = max(ans, (int)s.size()); for (auto& i : e1[cur]) dfs1(i); if (res) { s.erase(P(l[cur], cur)); if (~res) s.insert(P(l[res], res)); } } int main() { int T, n, t; scanf("%d", &T); while (T--) { cnt =ans= 0; scanf("%d", &n); for (int i = 1; i <= n; ++i) e1[i].clear(), e2[i].clear(); for (int i = 2; i <= n; ++i) scanf("%d", &t), e1[t].push_back(i); for (int i = 2; i <= n; ++i) scanf("%d", &t), e2[t].push_back(i); dfs2(1); dfs1(1); printf("%d\n", ans); } }