F2. Nearest Beautiful Number (hard version) (贪心)

注意到一个结论:答案和 n n n同位数,因为当所有位都为 9 9 9必定满足。

然后就可以贪心,找到满足不同位数 ≤ k \le k k的最大前缀 + 1 +1 +1的位置,显然此位需要加1,后面的位全部修改为 0 0 0,然后修改 n n n,直到 n n n满足条件为止。

e p : n = 4561 , k = 3 ep: n=4561,k=3 ep:n=4561,k=3

最大前缀是 456 456 456,需要对 1 1 1加不断 1 1 1,直到 n = 4564 n=4564 n=4564满足情况返回。
e p : n = 4512 , k = 2 ep:n=4512,k=2 ep:n=4512,k=2

最大前缀 45 45 45,第三位的 1 1 1 1 1 1,后面置为 0 0 0 n = 4520 n=4520 n=4520,然后再重新模拟。

n → 4530 → 4540 → 4544 n\rightarrow 4530\rightarrow 4540\rightarrow 4544 n453045404544

n n n的位数是 m m m位。

每位最多修改 10 10 10次,每次遍历最多 m m m位,最多遍历 m m m次。

时间复杂度: O ( 10 m 2 ) O(10m^2) O(10m2)

#include <bits/stdc++.h>
using namespace std;
string solve(){
	string n;
	int k;
	cin >> n >> k;
	while (true)
	{
		set<char> s;
		for (auto c : n) s.insert(c);
		if (s.size() <= k) return n;
		s.clear();
		int ptr = 0;
		for (; ; ptr++)
		{
			s.insert(n[ptr]);
			if (s.size() > k)
			{
				while (n[ptr] == '9')
					ptr--;
				n[ptr]++;
				for (int i = ptr + 1; i < n.size(); i++)
					n[i] = '0';
				break;
			}
		}
	} 
}
int main(){
	int t;
	cin >> t;
	while (t--)
		cout << solve() << '\n';	
	return 0;
}