1. 程式人生 > 其它 >Codeforces Round #740 (Div. 1, based on VK Cup 2021 - Final (Engine))

Codeforces Round #740 (Div. 1, based on VK Cup 2021 - Final (Engine))

A

直接按題意暴力模擬即可。時間複雜度為 \(O(t n^2)\)

程式碼:

#include <iostream>

using namespace std;

int a[1007];

inline bool check(int n){
	for (int i = 1; i <= n; i++){
		if (a[i] < a[i - 1]) return false;
	}
	return true;
}

int main(){
	int t;
	cin >> t;
	for (int i = 1; i <= t; i++){
		int n, ans = 0;
		cin >> n;
		for (int j = 1; j <= n; j++){
			cin >> a[j];
		}
		for (int j = 1; j <= n; j++){
			if (check(n)) break;
			for (int k = j % 2 == 0 ? 2 : 1; k < n; k += 2){
				if (a[k] > a[k + 1]) swap(a[k], a[k + 1]);
			}
			ans++;
		}
		cout << ans << endl;
	}
	return 0;
}

B

程式碼:

#include <stdio.h>

bool vis[200007];

inline int min(int a, int b){
	return a < b ? a : b;
}

int main(){
	int t;
	scanf("%d", &t);
	for (int i = 1; i <= t; i++){
		int a, b, sum, x, y, p, q, ansa = 0;
		scanf("%d %d", &a, &b);
		sum = a + b;
		x = sum / 2;
		y = (sum + 1) / 2;
		p = min(a, x);
		for (int j = 0; j <= sum; j++){
			vis[j] = false;
		}
		for (int j = 0; j <= p; j++){
			if (y >= a - j) vis[a + x - j * 2] = true;
		}
		q = min(b, x);
		for (int j = 0; j <= q; j++){
			if (y >= b - j) vis[b + x - j * 2] = true;
		}
		for (int j = 0; j <= sum; j++){
			if (vis[j]) ansa++;
		}
		printf("%d\n", ansa);
		for (int j = 0; j <= sum; j++){
			if (vis[j]) printf("%d ", j);
		}
		printf("\n");
	}
	return 0;
}

C

首先二分求出打完每個洞穴裡的怪獸所需的最小血量。顯然,先打所需血量較小的洞穴一定更優。

二分答案並在 check 函式中模擬打怪過程即可。時間複雜度為 \(O(t \log \max a_{i, j} \sum k)\)

程式碼:

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

typedef long long ll;

typedef struct {
	vector<int> v;
} Node;

int k[100007];
Node b[100007];

bool operator <(const Node a, const Node b){
	return a.v[0] < b.v[0];
}

inline bool check_each(int n, int m, ll k){
	int size = b[m].v.size();
	for (int i = 1; i < size; i++){
		if (k <= b[m].v[i]) return false;
		k++;
	}
	return true;
}

inline bool check(int n, ll k){
	ll cur = k;
	for (int i = 1; i <= n; i++){
		int size = b[i].v.size();
		for (int j = 1; j < size; j++){
			if (cur <= b[i].v[j]) return false;
			cur++;
		}
	}
	return true;
}

int main(){
	int t;
	cin >> t;
	for (int i = 1; i <= t; i++){
		int n;
		ll l = 1, r = 1e9 + 1, ans;
		cin >> n;
		for (int j = 1; j <= n; j++){
			ll LL = 1, rr = 1e9 + 1;
			cin >> k[j];
			b[j].v.clear();
			b[j].v.push_back(0);
			for (int x = 1; x <= k[j]; x++){
				int a;
				cin >> a;
				b[j].v.push_back(a);
			}
			while (LL <= rr){
				ll mid = (LL + rr) >> 1;
				if (check_each(n, j, mid)){
					rr = mid - 1;
					b[j].v[0] = mid;
				} else {
					LL = mid + 1;
				}
			}
		}
		sort(b + 1, b + n + 1);
		while (l <= r){
			ll mid = (l + r) >> 1;
			if (check(n, mid)){
				r = mid - 1;
				ans = mid;
			} else {
				l = mid + 1;
			}
		}
		cout << ans << endl;
	}
	return 0;
}