AGC006 題解

Include_Z_F_R_qwq發表於2024-10-30

目錄
  • A - Prefix and Suffix
  • B - Median Pyramid Easy

A - Prefix and Suffix

字串長度最小等價於兩個字串拼接後的“重疊部分”最長,列舉 \(s\) 的每一個字尾 \(s'\),再列舉 \(t\) 的長度為 \(|s'|\) 的字首 \(t'\),若 \(s' = t'\),則 \(s'\) 可作為重疊部分,找到滿足條件的最長的 \(s',t'\),答案即為 \(2n - |s'|\)

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll Read() {
	int sig = 1;
	ll num = 0;
	char c = getchar();
	while(!isdigit(c)) {
		if(c == '-') {
			sig = -1;
		}
		c = getchar();
	}
	while(isdigit(c)) {
		num = (num << 3) + (num << 1) + (c ^ 48);
		c = getchar();
	}
	return num * sig;
}
void Write(ll x) {
	if(x < 0) {
		putchar('-');
		x = -x;
	}
	if(x >= 10) {
		Write(x / 10);
	}
	putchar((x % 10) ^ 48);
}

int main() {
	string s, t;
	int n, i;
	cin >> n >> s >> t;
	for(i = n; i >= 1; i--) {
		if(s.substr(n - i, i) == t.substr(0, i)) {
			break;
		}
	}
	Write(2 * n - i);
	return 0;
}

B - Median Pyramid Easy

先考慮將 \(x\) 放在第 \(n\) 個位置(即正中間),我們嘗試將 \(x\) 從中間“傳送”上去。
一個直觀的想法是在其左右分別放置一個小於 \(x\) 的數和一個大於 \(x\) 的數。
我們會驚喜地發現,只要滿足上述條件就一定能把 \(x\) “傳送”上去!

證明:考慮 \(x\) 左上方的格子,設 \(x\) 左邊的格子裡的數為 \(y\)\(y\) 左邊的格子裡的數為 \(z\),分類討論:

  • \(z < y < x\),則中位數 \(y < x\)
  • \(y < z < x\),則中位數 \(z < x\)
  • \(y < x < z\),則中位數 \(x = x\)

可以發現無論怎樣,第 \(n - 1\) 列的數一定 \(\le x\),而同理可得第 \(n + 1\) 列的數一定 \(\ge x\),則一定保證 \(x\) 能被傳送上去。

所以任選 \(< x\)\(> x\) 的兩個數即可(程式碼中選用了 \(x - 1\)\(x + 1\) 兩個數),注意特判 \(x = 1,2n - 1\) 的情況。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll Read() {
	int sig = 1;
	ll num = 0;
	char c = getchar();
	while(!isdigit(c)) {
		if(c == '-') {
			sig = -1;
		}
		c = getchar();
	}
	while(isdigit(c)) {
		num = (num << 3) + (num << 1) + (c ^ 48);
		c = getchar();
	}
	return num * sig;
}
void Write(ll x) {
	if(x < 0) {
		putchar('-');
		x = -x;
	}
	if(x >= 10) {
		Write(x / 10);
	}
	putchar((x % 10) ^ 48);
}

const int N = 200005;
int a[N];
void Out(int n) {
	printf("Yes\n");
	int i;
	for(i = 1; i < 2 * n; i++) {
		Write(a[i]), putchar('\n');
	}
}
int main() {
	int n = Read(), x = Read(), i;
	if(x == 1 || x == 2 * n - 1) {
		printf("No");
		return 0;
	}
	for(i = 1; i < 2 * n; i++) {
		a[i] = i;
	}
	if(x == n) {
		Out(n);
	}
	else if(x == n - 1) {
		swap(a[x], a[x + 1]), swap(a[x - 1], a[x + 2]), Out(n);
	}
	else if(x == n + 1) {
		swap(a[x], a[x - 1]), swap(a[x + 1], a[x - 2]), Out(n);
	}
	else {
		swap(a[x], a[n]), swap(a[x - 1], a[n + 1]), swap(a[x + 1], a[n - 1]), Out(n);
	}
	return 0;
}