Codeforces Round #790 (Div. 4) A - H 题解
上次打了一场校赛,刚好和上次的 div2 冲了,最近又各种 ddl 轰炸,搞得没啥时间写题解
这场打下来感觉就是各种模板题
A. Lucky?
直接写,前三个数字的和等于后三个数字的和
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int main()
{
int t;
cin >> t;
while(t--)
{
int a = 0, b = 0;
for(int i=0; i<3; i++)
{
int x;
scanf("%1d", &x);
a += x;
}
for(int i=0; i<3; i++)
{
int x;
scanf("%1d", &x);
b += x;
}
if(a == b) cout << "yes" << endl;
else cout << "no" << endl;
}
return 0;
}
B. Equal Candies
直接找到数组的最小的,然后遍历一次看看其他都要拿走多少
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
int n;
cin >> n;
int minn = 1e9 + 7;
ll ans = 0;
for(int i=0; i<n; i++)
{
ll x;
cin >> x;
minn = x < minn ? x : minn;
ans += x;
}
cout << ans - minn * n << endl;
}
return 0;
}
C. Most Similar Words
直接暴力跑一遍,代价的话就是两个字母直接相减的绝对值
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
string s[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
int n, m;
cin >> n >> m;
for(int i=0; i<n; i++)
cin >> s[i];
int ans = m * 26;
for(int i=0; i<n; i++)
{
for(int j=i+1; j<n; j++)
{
int now = 0;
for(int k=0; k<m; k++)
{
int x = s[i][k] - s[j][k];
if(x < 0) x = -x;
now += x;
}
ans = now < ans ? now : ans;
}
}
cout << ans << endl;
}
return 0;
}
D. X-Sum
类似于 N 皇后的状态保存,处理斜边的和,左斜就是 x - y,右斜就是 x + y,然后数组开大点就行
最后遍历每一个点,代价是所属的两个斜边的和 减去 自身的重复
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 210;
const ll inf = 1e17 + 10;
ll num[maxn][maxn];
ll l[maxn * 4], r[maxn * 4];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
int n, m;
cin >> n >> m;
for(int i=0; i<n; i++) for(int j=0; j<m; j++) cin >> num[i][j];
for(int i=0; i<maxn * 4; i++) l[i] = r[i] = 0;
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
l[200 + i - j] += num[i][j];
r[i + j] += num[i][j];
}
}
ll ans = 0;
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
ll now = l[200 + i - j] + r[i + j] - num[i][j];
ans = now > ans ? now : ans;
}
}
cout << ans << endl;
}
return 0;
}
E. Eating Queries
二分板子题
排序后做前缀和,直接二分查找
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
ll num[maxn];
bool cmp(ll a, ll b)
{
return a > b;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
int n, m;
cin >> n >> m;
for(int i=1; i<=n; i++) {cin >> num[i];}
sort(num + 1, num + 1 + n, cmp);
for(int i=1; i<=n; i++) num[i] += num[i-1];
num[n + 1] = inf;
while(m--)
{
ll x;
cin >> x;
ll way = lower_bound(num + 1, num + n + 2, x) - num;
if(way == n + 1) way = -1;
cout << way << endl;
}
}
return 0;
}
F. Longest Strike
这题做的时候卡了半小时
直接用 map 装起来,然后遍历一次,不连续或者小于 k 就断开,然后记录最长是多少
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
map<int, int>vis;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
int n, m;
cin >> n >> m;
for(int i=0; i<n; i++)
{
int x;
cin >> x;
vis[x]++;
}
int way = 0, now = 0, maxx = 0, ans = 0;
for(auto it=vis.begin(); it!=vis.end(); it++)
{
if(now != it->first)
{
way = 0;
now = it->first;
}
if(it->second < m)
way = 0;
else
{
way++;
if(way > maxx)
{
maxx = way;
ans = it->first;
}
}
now++;
}
if(maxx == 0) cout << "-1" << endl;
else cout << ans - maxx + 1 << " " << ans << endl;
vis.clear();
}
return 0;
}
G. White-Black Balanced Subtrees
简单树型 dp 模板题
从根开始搜,当前树的黑白,通过先搜索子树的黑白数量,然后加起来,最后判断一下当前树是否符合平衡
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 4010;
const ll inf = 1e17 + 10;
vector<int>gra[maxn];
int l[maxn], r[maxn];
string s;
int dps(int now, int pre)
{
int ans = 0;
if(s[now-1] == 'W') l[now]++;
else r[now]++;
for(int i=0; i<gra[now].size(); i++)
{
int nex = gra[now][i];
if(nex == pre) continue;
ans += dps(nex, now);
l[now] += l[nex];
r[now] += r[nex];
}
return ans + (l[now] == r[now]);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
int n;
cin >> n;
for(int i=0; i<=n; i++) {l[i] = r[i] = 0; gra[i].clear();}
for(int i=2; i<=n; i++)
{
int x;
cin >> x;
gra[x].push_back(i);
}
cin >> s;
cout << dps(1, 1) << endl;
}
return 0;
}
H. Maximum Crossings
题目模型转化过来就是求逆序对
考虑树状数组 或者 归并排序 \(O(nlogn)\)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
ll tr[maxn];
int n;
inline int lowbit(int x)
{
return x & (-x);
}
void add(int x, ll val)
{
for(int i=x; i<=n; i+=lowbit(i))
tr[i] += val;
}
ll query(int x)
{
ll ans = 0;
while(x)
{
ans += tr[x];
x -= lowbit(x);
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
cin >> n;
for(int i=0; i<=n; i++) tr[i] = 0;
ll ans = 0;
for(int i=0; i<n; i++)
{
ll x;
cin >> x;
ans += i - query(x - 1);
add(x, 1);
}
cout << ans << endl;
}
return 0;
}