爆搜+剪枝 民间数据100pts
查看原帖
爆搜+剪枝 民间数据100pts
199821
LongDouble楼主2021/10/24 09:55

以下是 AC 代码

#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;

long long read() {
	long long ans = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-') f = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		ans = ans * 10 + (ch - '0');
		ch = getchar();
	}
	return ans * f;
}
int t, n, a[N], dfn[N];
int fst[N], snd[N], ant[N];
bool ok;
char ans[N];

void dfs(int dep, int l, int r, int ll, int lr) {
	if (dep > n * 2) {
		for (int i = 1; i <= n * 2; i++) putchar(ans[i]);
		printf("\n");
		ok = 1;
		return;
	}
	if (!dfn[a[l]] && !(dep > 1 && dep <= n && ant[l] != ll - 1 && ant[l] != lr + 1)) {
		//printf("%d\n", l);
		dfn[a[l]] = dep;
		ans[dep] = 'L';
		dfs(dep + 1, l + 1, r, min(ll, ant[l]), max(lr, ant[l]));
		dfn[a[l]] = 0;
	}
	else if (n * 2 - dfn[a[l]] + 1 == dep) {
		ans[dep] = 'L';
		dfs(dep + 1, l + 1, r, ll, lr);
	}
	if (ok) return;
	if (!dfn[a[r]] && !(dep > 1 && dep <= n && ant[r] != ll - 1 && ant[r] != lr + 1)) {
		dfn[a[r]] = dep;
		ans[dep] = 'R';
		//lstl = min(lstl, fst[a[r]]);
		//lstr = max(lstr, fst[a[r]]);
		dfs(dep + 1, l, r - 1, min(ll, ant[r]), max(lr, ant[r]));
		dfn[a[r]] = 0;
	}
	else if (n * 2 - dfn[a[r]] + 1 == dep) {
		ans[dep] = 'R';
		dfs(dep + 1, l, r - 1, ll, lr);
	}
}

int main() {
	//freopen("palin.in", "r", stdin);
	//freopen("palin.out", "w", stdout);
	t = read();
	while (t--) {
		n = read();
		for (int i = 1; i <= n; i++) fst[i] = snd[i] = 0;
		for (int i = 1; i <= n * 2; i++) {
			a[i] = read();
			if (!fst[a[i]]) fst[a[i]] = i;
			else snd[a[i]] = i;
		}
		for (int i = 1; i <= n; i++) ant[fst[i]] = snd[i], ant[snd[i]] = fst[i];
		//for (int i = 1; i <= n * 2; i++) printf("%d ", ant[i]);
		//printf("\n");
		ok = 0;
		dfs(1, 1, n * 2, n * 2 + 1, 0);
		if (!ok) printf("-1\n");
	}
	return 0;
}

民间数据疑似过弱

2021/10/24 09:55
加载中...