B. Diverse Substrings
思路:直接枚举超时,数的种类为0-9,所以对于每个位置只需往后延伸100位即可,超过100位必重复
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(fast)
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<cstring>
#include<math.h>
#include<map>#include<vector>
#define ms(x,y) memset(x,y,sizeof x)
#define fu(i,a,b) for(int i=a;i<=b;i ++ )
#define fd(i,a,b) for(int i=a;i>=b;i -- )
#define int long long
const int maxn=2e5+10,INF = 0x3f3f3f3f ;
using namespace std;
int a[maxn];int i,j,k;void solve() {int n; string s;cin >> n >> s;int ans = 0;for (int i = 0; i < n; i++) {vector<int> cnt(10);int Max = 0, sum = 0;for (int j = i; j < min(n, i + 100); j++) {if (++cnt[s[j] - '0'] == 1)sum++;Max = max(Max, cnt[s[j] - '0']);if (sum >= Max) ans++;}}cout << ans << endl;}
signed main()
{ios::sync_with_stdio(false);int t;cin >> t;while (t--) {solve();}}
B - Tying Rope
思路:vector二维数组存图,对于相连的全部度数为2则形成循环,否则不
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<cstring>
#include<math.h>
#include<map>
#include<vector>
#define int long long
const int maxn = 2e5 + 10;
using namespace std;
bool vis[maxn];
int d[maxn];
void solve() {int n, m;cin >> n >> m;vector<vector<int>>a(n + 1, vector<int>());for (int i = 1; i <= m; i++) {int u, v;char c1, c2;cin >> u >> c1 >> v >> c2;a[u].push_back(v);a[v].push_back(u);d[u]++, d[v]++;}memset(vis, 0, sizeof vis);int x = 0, y = 0;for (int i = 1; i <= n; i++) {if (!vis[i]) {queue<int> q;q.push(i);bool flag = 0;vis[i] = true;while (!q.empty()) {int qu = q.front();q.pop();if (d[qu] != 2)flag = 1;for (auto z : a[qu]) {if (!vis[z]) {q.push(z);vis[z] = true;}}}if (!flag)x++;elsey++;}}cout << x << ' ' << y << '\n';
}
signed main()
{ios::sync_with_stdio(false);solve();
}
B. Restore the Weather
思路1:最优策略(与k无关)为:排序为a,b均从小到大排序,根据a位置输出b位置,采用结构体排序
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(fast)
#include<iostream>#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<cstring>
#include<math.h>
#include<map>
#define int long long
const int maxn=2e5+10;
using namespace std;
int b[maxn];
struct node {int x;int y;
}a[maxn];
bool cmp(node A,node B) {return A.y < B.y;
}
bool cmp1(node A, node B) {return A.x < B.x;
}void solve(){int n, k;cin >> n >> k;for (int i = 1; i <= n; i++) {a[i].x = i;cin >> a[i].y;}for (int j = 1; j <= n; j++) {cin >> b[j];}sort(b + 1, b + 1 + n);sort(a + 1, a + 1 + n, cmp);for (int i = 1; i <= n; i++) {a[i].y = b[i];}sort(a + 1, a + 1 + n, cmp1);for (int i = 1; i <= n; i++) {cout << a[i].y << ' ';}cout << '\n';}
signed main()
{ios::sync_with_stdio(false);int t;cin >> t;while (t--) {solve();}
}
G. Hits Different
采用dp,dp公式 dp[i][j]=k*k+dp[i-1][j]+dp[i-1][j-1]-(重复部分)dp[i-2][j-1]
#include<iostream>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
const int maxn = 1e6 + 10;
int dp[3000][3000];
int a[maxn];
void solve() {int n;cin >> n;cout << a[n] << '\n';}
void init() {dp[1][1] = 1;a[1] = 1;int k = 2;for (int i = 2; i <= 3000; i++) {for (int j = 1; j <= i && k <= 1000000; j++, k++) {dp[i][j] = k * k + dp[i - 1][j] + dp[i - 1][j - 1] - dp[i - 2][j - 1];a[k] = dp[i][j];}}
}
signed main()
{ios::sync_with_stdio(false);init();int t;cin >> t;while (t--) {solve();}
}
C.Zero - Sum Prefixes
思路:无论前面怎么操作,前缀和在这个位置保持一致
最优操作把出现0位置后前缀和值出现最多的次数变成0,统计相加,最后加上第一个0前面前缀和为0个数
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(fast)
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<cstring>
#include<math.h>
#include<map>
#include<vector>
#define ms(x,y) memset(x,y,sizeof x)
#define int long long
const int maxn = 2e5 + 10, INF = 0x3f3f3f3f;
using namespace std;
int a[maxn], b[maxn];
int i;
void solve() {int n;cin >> n;int ans = 0;vector<int>v;for (int i = 1; i <= n; i++) {cin >> a[i];b[i] = a[i] + b[i - 1];if (a[i] == 0) {v.push_back(i);}}v.push_back(n + 1);map<int, int>cnt;for (int i = 1; i < v.size(); i++) {int Max = 0;cnt.clear();for (int j = v[i-1]; j < v[i]; j++) {cnt[b[j]]++;Max = max(Max, cnt[b[j]]);}ans += Max;}for (int i = 1; i < v[0]; i++) {if (b[i] == 0) {ans++;}}cout << ans << '\n';
}
signed main()
{ios::sync_with_stdio(false);int t;cin >> t;while (t--) {solve();}
}
lower_bound() 函数用于在指定区域内查找不小于目标值的第一个元素。
c++语言中,multiset是<set>库中一个非常有用的类型,它可以看成一个序列,插入一个数,删除一个数都能够在O(logn)的时间内完成,
而且他能时刻保证序列中的数是有序的,而且序列中可以存在重复的数。(可搭配erase,lower_bount使用)
自定义排序bool cmp(类型 A,类型 B){};