CodeForces 1560F2. Nearest Beautiful Number (hard version)(暴力)
阿新 • • 發佈:2021-08-19
題目大意
給你一個n,求只包含k個不同數字且大於等於n的最小的數。
解題思路
我們想要符合條件的數字儘量小,可以想到的一個暴力方法就是不斷的讓n加1,直到符合條件為止,觀察最後得到的數,不難發現其結果要麼是等於原數,要麼是前面某一位比n大,然後後面全是k個不同數字中最小的數,所以我們可以不考慮後面那些最小的數,就看前幾位怎麼搞能得到解。
題目要求用k個不相同的數字,我們就從有k+1個不相同的數字的字首開始+1,不考慮後面的數字放多少(最後肯定放k個數字中最小的數),不斷的迴圈,直到得到一個數的是由k個不同的數字形成的字首+後面若干個0為止,後面0的位置全放k個數中最小的數即可。由於每次進位之後後面的位置就不考慮了,所以頂多就加100次左右。
const int maxn = 2e5+10; const int maxm = 2e7+10; int calc(int x) { int cnt = 0; ll res = 0; while(x) { res |= (1<<(x%10)); x /= 10; } while(res) { res -= res&-res; ++cnt; } return cnt; } int main() { IOS; int __; cin >> __; while(__--) { ll n, k; cin >> n >> k; while(calc(n)>k) { ll f = n, t = 1; while(calc(f/10)>k) { f /= 10; t *= 10; } ; ++f; n = f*t; } cout << n << endl; } return 0; }
f1寫的十分醜陋的分類討論
const int maxn = 1e5+10; const int maxm = 1e6+10; int main() { IOS; int __; cin >> __; while(__--) { string n; int k; cin >> n >> k; char a = n[0]; string ans; ans = 'a'; for (char b = '0'; b<='9'; ++b) { string t; int f = 0; if (k==1) a = b; char ch1 = max(a, b); char ch2 = min(a, b); for (int i = 0; i<n.size() && f>=0; ++i) { char ch = n[i]; if (f==1) t += ch2; else if (i+1<n.size() && n[i+1]>ch1) { if (ch2>n[i]) { t += ch2; f = 1; } else if (ch1>n[i]) { t += ch1; f = 1; } else f = -1; } else if (i+1<n.size() && n[i+1]==ch1) { bool ok = 0; for (int j = i+1; j<n.size(); ++j) { if (n[j]<ch1) break; if (n[j]>ch1) { ok = 1; break; } } if (!ok) { if (ch2>n[i]) { t += ch2; f = 1; } else if (ch2==n[i]) t += ch2; else if (ch1>n[i]) { t += ch1; f = 1; } else if (ch1==n[i]) t += ch1; else f = -1; } else { if (ch2>n[i]) { t += ch2; f = 1; } else if (ch1>n[i]) { t += ch1; f = 1; } else f = -1; } } else if (ch2>n[i]) { t += ch2; f = 1; } else if (ch2==n[i]) t += ch2; else if (ch1>n[i]) { t += ch1; f = 1; } else if (ch1==n[i]) t += ch1; else f = -1; } if (f!=-1) ans = min(ans, t); } cout << ans << endl; } return 0; }