数组A中给定可以使用的1~9的数,返回由A数组中的元素组成的小于n(n > 0)的最大数。 例如:A = {1, 2, 4, 9},n = 2533,返回2499。
题解
贪心思路
题目很好理解,但没写对呜呜呜
cpp
#include <iostream>
#include <vector>
#include <unordered_set>
using namespace std;
int getMaxD(vector<int> &a, int x)
{
for (auto it = a.rbegin(); it != a.rend(); it++)
{
if (*it < x)
{
return *it;
}
}
return 0;
}
int solve(vector<int> &a, int n)
{
// 分解 n
vector<int> nvec;
while (n > 0)
{
int tmp = n % 10;
nvec.push_back(tmp);
n = n / 10;
}
// 排序可以使用的数组
sort(a.begin(), a.end());
// 记录有哪一些数字可以用
unordered_set<int> st;
for (auto v : a)
{
st.insert(v);
}
// 存储答案
vector<int> ans(nvec.size());
// 需要特判一下数组只有一个的情况
if (a.size() == 1)
{
if (nvec[nvec.size() - 1] <= a[0])
{
int ans = 0;
for (int i = 0; i < nvec.size() - 1; i++)
{
ans *= 10;
ans += a[0];
}
return ans;
}
else
{
int ans = 0;
for (int i = 0; i < nvec.size() - 1; i++)
{
ans *= 10;
ans += a[0];
}
return ans;
}
}
// 从给定的数字n的高位开始选择数字
for (int i = nvec.size() - 1; i >= 0; i--)
{
cout << i << endl;
// 除了最后一位,其他位数能找到和原来数n的位数一样的,那就优先选
if (i > 0 && st.find(nvec[i]) != st.end())
{
ans[i] = nvec[i];
continue; // 选完后直接跳过
}
// 如果没找到一样的数字
// 那就找一个比nvec[i]小的数字
// 如果找到了,那后面就不用比较了,直接选最大的数字就行
// 所以直接跳出
auto d = getMaxD(a, nvec[i]);
if (d > 0)
{
ans[i] = d;
break;
}
// 如果剩余数字都比当前n的位数上要大
// 开始回溯,即上一位重新选择
// 上一位通过getMaxD函数选择小于当前位数的数(从给定数字中)
for (i++; i < nvec.size(); i++)
{
ans[i] = 0;
cout << i << endl;
// 如果有,那就直接跳出循环,剩余位数选最大值即可
d = getMaxD(a, nvec[i]);
if (d > 0)
{
ans[i] = d;
break;
}
// 如果一直回溯到第一个数字了,都没找到合适的
// 那说明和原来n数字一样长的答案不存在
if (i == nvec.size() - 1)
{
cout << i << endl;
ans.resize(nvec.size() - 1);
cout << ans.size() << endl;
}
}
break;
}
int res = 0;
// cout << ans.size() << endl;
for (int i = ans.size() - 1; i >= 0; i--)
{
res *= 10;
if (ans[i] > 0)
{
res += ans[i];
continue;
}
res += a.back();
}
return res;
}
int main()
{
auto a = vector<int>{4};
int n = 23333;
int res = solve(a, n);
cout << res << endl;
return 0;
}
DFS
后面有空再补吧。