输入: A = a 1 , a 2 , . . . , a m ( 0 < = a i < = 9 , 1 < = m < = 10 ) ; n A = {a_1,a_2,...,a_m}(0<=a_i<=9,1<=m<=10);n A=a1,a2,...,am(0<=ai<=9,1<=m<=10);n
输出:构造小于n的最大数(可重复使用 a i a_i ai)
思路
从 n 的最高位开始遍历,考虑当前位置可取的最大 a i ,使用 s t a c k 来存储每一位选择的 a 从n的最高位开始遍历,考虑当前位置可取的最大a_i,使用stack来存储每一位选择的a 从n的最高位开始遍历,考虑当前位置可取的最大ai,使用stack来存储每一位选择的a
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int mod = 1e9 + 7;
void solve() {
int A[] = {9, 8};
int n = 9;
n --;
map<int, int> mp;
for(auto x: A) mp[x] = 1;
int a[10], cnt = 0;
while(n) {
a[cnt ++] = n % 10;
n /= 10;
}
function<int(int)> fin = [&](int x) -> int {
for(int i = x; i >= 0; -- i) {
if(mp[i]) return i;
}
return -1;
};
bool f = false;
stack<int> st;
if(fin(a[cnt - 1]) == -1) {
for(int i = cnt - 2; i >= 0; -- i) {
st.push(fin(9));
}
} else {
for(int i = cnt - 1; i >= 0; -- i) {
if(f) {
st.push(fin(9));
continue;
}
int x = fin(a[i]);
if(x == -1) {
while(!st.empty()) {
int _x = st.top();
x = fin(_x - 1);
st.pop();
i ++;
if(x == -1) continue;
st.push(x);
f = true;
break;
}
} else {
if(x != a[i]) f = true;
st.push(x);
}
}
}
string ans = "";
while(!st.empty()) {
ans = char(st.top() + '0') + ans;
st.pop();
}
cout << ans << '\n';
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#ifdef ACM_LOCAL
freopen("in", "r", stdin);
freopen("out", "w", stdout);
signed test_index_for_debug = 1;
char acm_local_for_debug = 0;
do {
if (acm_local_for_debug == '$') exit(0);
if (test_index_for_debug > 20)
throw runtime_error("Check the stdin!!!");
auto start_clock_for_debug = clock();
solve();
auto end_clock_for_debug = clock();
cout << "Test " << test_index_for_debug << " successful!" << endl;
cerr << "Test " << test_index_for_debug++ << " Run Time: "
<< double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
cout << "--------------------------------------------------" << endl;
} while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
solve();
#endif
return 0;
}