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还是有很大的欠缺的。还有遇到暂时想不出来的题先跳过,可能后面的题更简单。。。。

posted @ 2022-05-11 11:18  飘向远方丶  阅读(66)  评论(0)    收藏  举报