Educational Codeforces Round 96 A-E 題解

hujin066發表於2020-10-11

https://codeforces.com/contest/1430

A - Number of Apartments

沒有仔細思考,直接暴力寫了。
列舉5個、7個窗戶房子的個數,最多總迴圈次數1e7

#include<bits/stdc++.h>
 
using namespace std;
int main(){
	int t = 0;
	cin>>t;
	while(t--){
		int n;
		scanf("%d",  &n);
		int i = 0, j = 0, k = 0;
		bool ok = false;
		for(;i*7 <= n; i++){
			int x = i * 7;
			for(j=0;x +  j * 5 <= n; j++){
				if((n - i * 7 - j * 5)%3 == 0){
					ok = true;
					printf("%d %d %d\n", (n - i * 7 - j * 5) / 3, j, i);
					break;
				}
			}
			if(ok)break;
		}
		if(!ok)puts("-1");
	}
} 

B - Barrels

最優方法是取水前k+1 ~ 2多的桶,全部倒到最多的桶中

#include<bits/stdc++.h>

using namespace std;
const int maxn = 300000;
int a[maxn];
typedef long long LL;
int main(){
	int t = 0;
	cin>>t;
	while(t--){
		int n, k;
		scanf("%d%d", &n, &k);
		for(int i = 0; i < n; i++)
			scanf("%d", a+i);
		sort(a, a+n);
		LL ans = 0;int j = 0;
		for(int i = n-2; i >= 0 && j < k; i--)ans += a[i], j++;
		ans += a[n-1];
		cout<<ans<<endl;
	}
} 

C - Numbers on Whiteboard

每次操作時考慮最優化全部數的均值,到最後一次時是最優的。因此每次取最大的兩個數,計算平均值向上取整,放回黑板。可以用優先佇列維護。

若是選取奇數,向上取整後代價不會超過選取更小的數,因此不影響結果。

#include<bits/stdc++.h>

using namespace std;
const int maxn = 300000;
typedef long long LL;

int main(){
	int t = 0;
	cin>>t;
	while(t--){
		int n;
		scanf("%d", &n);
		int ans;
		priority_queue<int>que;
		vector<pair<int, int> > op;
		for(int i = 0; i < n; i++)que.push(i+1);
		for(int i = 0; i < n-1; i++){
			int x = que.top();
			que.pop();
			int y = que.top();
			que.pop();
			que.push((x+y+1)/2);
			op.push_back({x, y});
		}
		printf("%d\n", que.top());
		for(int i = 0; i < n-1; i++)
			printf("%d %d\n", op[i].first, op[i].second);
	}
} 

D - String Deletion

模擬+貪心。注意到如果第一步操作刪除連續多個序列中的一個,不會使第二步操作的次數減少。第一步操作每次刪除當前位置後第一個連續序列的字元即可。如果不存在,則刪除首字元。需要預處理下一個連續字元的位置。

實現的有點冗餘。

#include<bits/stdc++.h>

using namespace std;
const int maxn = 300000;

typedef long long LL;
int nxt[maxn];
int jump[maxn];
int main(){
	int t = 0;
	cin>>t;
	while(t--){
		int n;
		scanf("%d", &n);
		string s;
		cin>>s;
		int con = 0;
		char pre = s[0];
		int j = 0;
		for(int i = 0; i < n+10; i++){
			nxt[i] = -1;
			jump[i] = 0;
		}
		for(int i = 1; i < n; i++){
			if(s[i] == pre){
				while(j <= i-1)nxt[j++] = i-1;
			}
			pre = s[i];
		}
		int ans = 0;
		j = 0;
		for(int i = 0; i < n;){
			ans++;
			while(jump[i]) i++;
			if(i >= n)break;
			j = max(j, i);
			if(nxt[j] != -1){
				if(i == nxt[j])i++;
				else {
					jump[nxt[j]] = 1;
					j++;
					if(nxt[j] != -1) 
					while(jump[nxt[j]])j++;
				}
				while(jump[i]) i++;
				pre = s[i];
				i++;
				while(jump[i]) i++;
				while(i < n && s[i] == pre ){
					i++;
					while(jump[i]) i++;
				}
			}
			else{
				i++;
				while(jump[i]) i++;
				pre = s[i];
				i++;
				while(jump[i]) i++;
				while(i < n && s[i] == pre ){
					i++;
					while(jump[i]) i++;
				}
			}
			if(i >= n)break;
		}
		cout<<ans<<endl;
	}
} 

E - String Reversal

置換數=逆序對數。為翻轉前每個字元編號,相鄰相同字元編號相同,表示可以任意對換位置。否則後字元=前字元編號+1。

翻轉後所有編號反序。為了儘量減少逆序對數量,相同字元內編號可再次反序。最後得到的編號求逆序對數即可。

逆序對數用了模板

#include<bits/stdc++.h>

using namespace std;
const int maxn = 250000;

typedef long long LL;
int pp[26][maxn];
int cnt[26] = {};
int a[maxn];int tmpA[maxn];
LL ans = 0;


void merge_sort(int l, int r, int *A) {
	if (l >= r) return ;
	int mid = (l + r) >> 1;
	merge_sort(l, mid, A);
	merge_sort(mid + 1, r, A);
	int pl = l, pr = mid + 1, tmpp = 0;
	while(pl <= mid && pr <= r) {
		if (A[pl] <= A[pr]) tmpA[tmpp++] = A[pl++];
		else tmpA[tmpp++] = A[pr++], ans += mid - pl + 1;
	}
	while(pl <= mid) tmpA[tmpp++] = A[pl++];
	while(pr <= r) tmpA[tmpp++] = A[pr++];
	for (int i = 0; i < tmpp; i++) A[i + l] = tmpA[i];
}
int main(){
	int n;
	scanf("%d", &n);
	string s;
	cin>>s;
	for(int i = 0; i < n; i++)s[i] -= 'a';
	pp[s[0]][0] = 1;
	int pre = s[0];
	cnt[s[0]] = 1;
	int pos = 1;
	for(int i = 1; i < n; i++) {
		if(s[i] != pre) pos++;
		pp[s[i]][cnt[s[i]]++] = pos;
		pre = s[i];
	}
	
	for(int i = 0; i < n; i++) {
		a[i] = pp[s[i]][--cnt[s[i]]];
		a[i] = n + 1 - a[i];
		//cout<<a[i]<<endl;
	}
	merge_sort(0, n-1, a);
	cout<<ans<<endl;
} 

相關文章