Codeforces Round #790 (Div. 4)
A - Lucky?
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
const int N = 2e5 + 10;
int w[N];
void solve() {
string s;
cin >> s;
int a = 0, b = 0;
for(int i = 0; i < s.size(); i++) {
if(i < 3) a += s[i] - '0';
else b += s[i] - '0';
}
if(a == b) cout << "YES" << endl;
else cout << "NO" << endl;
}
signed main() {
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
B - Equal Candies
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
const int N = 2e5 + 10;
int w[N];
void solve() {
int n;
cin >> n;
for(int i = 0; i < n; i++) cin >> w[i];
int ans = 0;
sort(w, w + n);
for(int i = 1; i < n; i++) {
ans += w[i] - w[0];
}
cout << ans << endl;
}
signed main() {
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
C - Most Similar Words
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
const int N = 2e5 + 10;
//int w[N];
char s[60][10];
void solve() {
int n, m;
cin >> n >> m;
for(int i = 0; i < n; i++) cin >> s[i];
int ans = 1e6;
for(int i = 0; i < n; i++) {
for(int j = i + 1; j < n; j++) {
int t = 0;
for(int k = 0; k < m; k++) {
t += abs(s[i][k] - s[j][k]);
}
ans = min(t, ans);
}
}
cout << ans << endl;
}
signed main() {
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
D - X-Sum
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
const int N = 2e5 + 10;
//int w[N];
int w[210][210];
int n, m;
int f(int x, int y) {
int t = 0;
int a = x, b = y;
// zhu
while(a < n && b < m) {
t += w[a][b];
a++,b++;
}
a = x, b = y;
while(a >= 0 && b >= 0) {
t += w[a][b];
a--,b--;
}
// fu
a = x, b = y;
while(a < n && b >= 0) {
t += w[a][b];
a++,b--;
}
a = x, b = y;
while(a >= 0 && b < m) {
t += w[a][b];
a--,b++;
}
a = x, b = y;
t -= 3ll * w[a][b];
return t;
}
void solve() {
cin >> n >> m;
memset(w, 0, sizeof w);
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++) {
cin >> w[i][j];
}
int ans = 0;
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
int t = f(i,j);
ans = max(t, ans);
}
}
cout << ans << endl;
}
signed main() {
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
E - Eating Queries
思路: 从大到小排序,求前缀和,再二分。
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
const int N = 2e5 + 10;
int w[N];
int s[N];
bool cmp(int a, int b) {
return a > b;
}
void solve() {
int n, m;
cin >> n >> m;
memset(s, 0, sizeof s);
for(int i = 1; i <= n; i++) {
cin >> w[i];
}
sort(w + 1, w + n + 1, cmp);
for(int i = 1; i <= n; i++) s[i] = s[i-1] + w[i];
while(m--) {
int x;
cin >> x;
int l = 1, r = n;
while(l < r) {
int mid = l + r >> 1;
if(s[mid] < x) l = mid + 1;
else r = mid;
}
if(s[l] >= x) cout << l << endl;
else cout << -1 << endl;
}
}
signed main() {
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
F - Longest Strike
这里要用到map,可惜我对map不怎么熟悉,导致做不出来。问题也很明显,要加深对STL函数的了解,以便在比赛中运用自如。
思路:先找到数量大于等于k的数,然后将他们排序,用双指针找到最长长度即可。
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
#define pb push_back
void solve() {
int n, k;
cin >> n >> k;
map<int,int>mp;
for(int i = 0; i < n; i++) {
int x;
cin >> x;
mp[x]++;
}
vector<int>ve;
for(auto x : mp) {
if(x.se >= k) ve.pb(x.fi);
}
if(ve.size() == 0) {
cout << -1 << endl;
return;
}
int mx = 0, lans = ve[0], rans = ve[0], l = ve[0];
for(int i = 1; i < ve.size(); i++) {
if(ve[i] - 1 == ve[i-1]) {
if(ve[i] - l > mx) {
lans = l;
rans = ve[i];
mx = ve[i] - l;
}
}
else {
l = ve[i];
}
}
cout << lans << ' ' << rans << endl;
}
signed main() {
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
G - White-Black Balanced Subtrees
对dfs还是不够熟练,感觉是自己的思维有问题。勤加练习
思路:dfs,看每颗子树的黑白是否相同,然后往上回退,父节点继承子节点的个数。
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
#define pb push_back
const int N = 4010;
int e[N], ne[N], h[N], idx, ans;
char s[N];
int w[N];
void dfs(int u, int sum) {
w[u] = s[u] == 'W' ? 1 : -1;
for(int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if(j != u) {
dfs(j, 0);
w[u] += w[j];
}
}
ans += !w[u];
}
void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
void solve() {
int n;
cin >> n;
memset(h, -1, sizeof h);
memset(ne, 0, sizeof ne);
memset(e, 0, sizeof e);
memset(w, 0, sizeof w);
idx = 0, ans = 0;
for(int i = 2; i <= n; i++) {
int x;
cin >> x;
add(x, i);
}
for(int i = 1; i <= n; i++) cin >> s[i];
dfs(1, 0);
cout << ans << endl;
}
signed main() {
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
H1 - Maximum Crossings (Easy Version)
求逆序对的数量(相等的也算) 可以用到模板 归并排序求逆序对的数量了,卡在了F,没做到H,要不然就舒服了。
代码:
#include <iostream>
#include <algorithm>
using namespace std;
#define int long long
const int N = 100010;
int q[N], t[N];
int n;
int merge_sort(int *q, int l, int r) {
if(l >= r) return 0;
int ans = 0, mid = (l + r) / 2;
ans = merge_sort(q, l, mid) + merge_sort(q, mid + 1, r);
int i = l, j = mid + 1, k = 0;
while(i <= mid && j <= r) {
if(q[i] < q[j]) t[k++] = q[i++];
else {
ans += mid - i + 1;
t[k++] = q[j++];
}
}
while(i <= mid) t[k++] = q[i++];
while(j <= r) t[k++] = q[j++];
for(int i = l, k = 0; i <= r; i++, k++) q[i] = t[k];
return ans;
}
void solve() {
cin >> n;
for(int i = 0; i < n; i++) cin >> q[i];
int ans = merge_sort(q, 0, n - 1);
cout << ans << endl;
}
signed main() {
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
H2 - Maximum Crossings (Hard Version)
同H1 归并排序的做法是0(nlogn)的;
代码:
#include <iostream>
#include <algorithm>
using namespace std;
#define int long long
const int N = 2e5 + 10;
int q[N], t[N];
int n;
int merge_sort(int *q, int l, int r) {
if(l >= r) return 0;
int ans = 0, mid = (l + r) / 2;
ans = merge_sort(q, l, mid) + merge_sort(q, mid + 1, r);
int i = l, j = mid + 1, k = 0;
while(i <= mid && j <= r) {
if(q[i] < q[j]) t[k++] = q[i++];
else {
ans += mid - i + 1;
t[k++] = q[j++];
}
}
while(i <= mid) t[k++] = q[i++];
while(j <= r) t[k++] = q[j++];
for(int i = l, k = 0; i <= r; i++, k++) q[i] = t[k];
return ans;
}
void solve() {
cin >> n;
for(int i = 0; i < n; i++) cin >> q[i];
int ans = merge_sort(q, 0, n - 1);
cout << ans << endl;
}
signed main() {
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
总结:
A-E做的很顺,比上次div4进步了很多,但是对于dfs,模拟,STL还是有很大的欠缺的。还有遇到暂时想不出来的题先跳过,可能后面的题更简单。。。。

浙公网安备 33010602011771号