LY1153 [ 20230317 CQYC省选模拟赛 T3 ] 灵能潮汐

题意

给定一个长度为 \(n\) 的字符串 \(s\)

让你确定一个答案 \(x\),使得 \(x + i - 1\) 的十进制上有 \(s_i\)

Sol

不难想到考虑从低往高位讨论,讨论当前这位选的数字是多少。

对于这 \(n\) 个限制,将 \(x + i - 1 = s_i\) 的限制删掉。

发现如果将每相邻 \(10\) 个限制合并,高一位的限制依然满足连续,依然可以使用相同的方法合并,注意到总状态为 \(10 ^ {log_10 ^ {n}} = n\)

总复杂度:\(O(n \log n)\)

Code

#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <array>
#include <vector>
#define ll long long
#define il inline
#define rg register
using namespace std;
#ifdef ONLINE_JUDGE

#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
char buf[1 << 23], *p1 = buf, *p2 = buf, ubuf[1 << 23], *u = ubuf;

#endif
il int read() {
	rg int p = 0, flg = 1;
	rg char c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-') flg = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') {
		p = p * 10 + c - '0';
		c = getchar();
	}
	return p * flg;
}
il string read_() {
	rg string ans;
	rg char c = getchar();
	while (c < '0' || c > '9')
		c = getchar();
	while (c >= '0' && c <= '9')
		ans += c, c = getchar();
	return ans;
}
il void write(ll x) {
	if (x < 0) {
		x = -x;
		putchar('-');
	}
	if (x > 9) {
		write(x / 10);
	}
	putchar(x % 10 + '0');
}
const int N = 1e6 + 5;
array <int, N> ksl;

il ll divide(vector <int> &isl, bool flg) {
	if (isl.size() == 1) {
		int cnt = 0;
		for (rg int i = 0; i <= 9; i++)
			if (isl.front() & (1 << i))
				cnt++, ksl[cnt] = i;
		if (!cnt) return !flg;
		if (cnt == 1 && !ksl[1]) return 10;
		if (cnt == 1) return ksl[1];
		if (!ksl[1]) swap(ksl[1], ksl[2]);
		rg int res = 0;
		for (int i = 1; i <= cnt; i++) res = res * 10 + ksl[i];
		/*
		rg vector <int> tp;

		if (tp.empty()) return !flg;
		if (tp.size() == 1 && !tp.front()) return 10;
		if (tp.size() == 1) return tp.front();
		if (!tp.front()) swap(tp[0], tp[1]);
		*/
		return res;
	}
	if (flg && !isl.front()) {
		rg bool tp = 1;
		for (rg int i = 1; i < (int)isl.size(); i++) {
			rg int k = i, tp0 = 0;
			while (k) tp0 |= 1 << (k % 10), k /= 10;
			if (isl[i] != (isl[i] & tp0)) {
				tp = 0;
				break;
			}
		}
		if (tp) return 0;
	}
	rg ll ans = 2e18;
	for (rg int i = 0; i <= 9; i++) {
		if (isl.size() == 2 && i == 9 && (isl[0] & ~(1 << 9)) == isl[0] && (isl[1] & ~1) == isl[1]) continue;
		rg vector <int> tp;
		rg int tp0 = 0, tp1 = i;
		for (rg int j = 0; j < (int)isl.size(); j++) {
			/* cnt++; */
			if (tp1 == 10) {
				tp.push_back(tp0);
				tp0 = tp1 = 0;
			}
			tp0 |= isl[j] & ~(1 << tp1), tp1++;
		}
		tp.push_back(tp0);
		ans = min(ans, divide(tp, i > 0) * 10 + i);
	}
	return ans;
}

il void solve() {
	rg int n = read();
	rg string str = read_();
	rg vector <int> isl;
	for (rg auto k : str)
		isl.push_back(1 << (k - '0'));
	write(divide(isl, 0)), puts("");
}

signed main() {
	/* freopen("pulse.in", "r", stdin); */
	/* freopen("pulse.out", "w", stdout); */
	rg int T = read();
	while (T--) solve();
	/* cerr << cnt << endl; */
	return 0;
}
posted @ 2024-01-23 09:53  cxqghzj  阅读(4)  评论(0编辑  收藏  举报