题目大意:
给定一组数字字符串,其中包含一个大数和大数的长度,且这些数字被随机存储
第二行为大数包含的子数列求出这个大数能够得到的最小数
题解:
首先求出大数的长度
len为数字字符串的长度,digits从0递增判断(len-digits)的位数+(len-digits)是否与len相等求出大数的长度
接着求最小数
方法一(有些复杂):
把整个数列分成3部分子数列前pre,子数列,子序列后
基本上是贪心加特殊处理。
#include <cstdio>
#include <set>
#include <vector>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
int cnt[13];
string s;
string remaind, tt;
int len, ll;
int main()
{
cin>> s;
cin>>tt;
int len = s.length();
int n = 0;
ll = 0;
if (len == 2)
{
cout << tt << endl;
return 0;
}
for (int i = 0; i < 10; i++)
{
cnt[i] = 0;
}
for (int i = 0; i < len; i++)
{
cnt[s[i]-'0']++;
}
int t = len-1;
int digits = 1;
int dt;
int f = t;
dt = 0;
while (f > 0)
{
f/=10;
dt++;
}
while (t+dt != len)
{
digits++;
t = len-digits;
int f = t;
dt = 0;
while (f > 0)
{
f/=10;
dt++;
}
}
len = t;
while (t)
{
cnt[t%10]--;
t /= 10;
}
int firstt = tt[0]-'0', flag = 0, mintt = 1;
for (int i = 0; i < tt.length(); i++)
{
cnt[tt[i]-'0']--;
if (i != 0 && !flag)
{
if (tt[i]-'0' < firstt)
{
flag = 1;
mintt = tt[i]-'0';
}
else if (tt[i]-'0' > firstt)
flag = 2;
}
}
int countzero = 0;
if (mintt == 0)
{
int flagg = 0;
for (int i = 0; i < tt.length(); i++)
{
if (tt[i] == '0')
{
flagg = 1;
countzero++;
}
else if (flagg == 1)
{
flag = 3;
break;
}
}
if (flag == 3 && countzero > cnt[0])
flag = 1;
}
for (int i = 1; i < 10; i++)
{
if (cnt[i] > 0)
{
ll = i;
break;
}
}
string result;
if (firstt != 0 && ll != 0)
{
if (ll < firstt)
{
result += (char)(ll+'0');
cnt[ll]--;
for (int i = 0; i < firstt; i++)
{
while (cnt[i] > 0)
{
result += (char)(i+'0');
cnt[i]--;
}
ll = i+1;
}
}
else if (ll == firstt && cnt[0] > 0 && (mintt != 0 || flag != 1))
{
result += (char)(ll+'0');
cnt[ll]--;
while (cnt[0] > 0)
{
result += '0';
cnt[0]--;
}
}
if (ll == firstt && flag != 1 && flag != 3)
{
while (cnt[ll] > 0)
{
result += (char)(ll+'0');
cnt[ll]--;
}
ll = ll+1;
}
}
else if (ll != 0)
{
result += (char)(ll+'0');
cnt[ll]--;
while (cnt[0] > 0)
{
result += '0';
cnt[0]--;
}
}
result += tt;
for (int i = 0; i < 10; i++)
{
while (cnt[i] > 0)
{
result += (char)(i+'0');
cnt[i]--;
}
}
cout << result << endl;
return 0;
}
方法二:
把整个数列分成3部分子数列前pre,子数列,子序列后
首先
将字符串best弄成子数列+子序列后的字符串
接着
设置子序列前的首字母为除0最小数字
循环i从0~9 :
在子序列前添加为i的全部数字
判断best是否大于该序列+子序列+子序列后
是就修改
结束循环
输出
#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <numeric>
#include <iomanip>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <vector>
#include <math.h>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
typedef long double ld;
template <typename T>
T nextInt()
{
T x = 0, p = 1;
char ch;
do
{
ch = getchar();
}
while(ch <= ' ');
if (ch == '-')
{
p = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
x = x * 10 + (ch - '0');
ch = getchar();
}
return x * p;
}
const int maxN = (int)1e6 + 10;
const int maxL = 17;
const int INF = (int)1e9;
const int mod = (int)1e9 + 7;
const ll LLINF = (ll)1e18;
vector <int> a(10);
vector <int> b(10);
char s[maxN];
char t[maxN];
string get(const vector<int>&cnt)
{
string ret = "";
for (int i = 0; i < 10; ++i)
{
ret += string(cnt[i], char('0' + i));
}
return ret;
}
int main()
{
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
gets(s);
gets(t);
if (strcmp(s, "01") == 0 || strcmp(s, "10") == 0)
{
puts("0");
return 0;
}
int n = strlen(s);
int m = strlen(t);
for (int i = 0; i < n; ++i)
{
a[s[i] - '0']++;
}
for (int i =0 ; i < m; ++i)
{
b[t[i] - '0']++;
}
string T = (const char *) t;
for (int len = 1; ; ++len)
{
vector <int> cnt = a;
int tmp = len;
int c = 0;
while(tmp > 0)
{
cnt[tmp % 10]--;
tmp /= 10;
c++;
}
bool ok = true;
for (int i = 0; i < 10; ++i)
{
cnt[i] -= b[i];
if (cnt[i] < 0) ok = false;
}
if (ok && (t[0] != '0' || *max_element(cnt.begin() + 1, cnt.end())) > 0 && n - c == len)
{
}
else continue;
bool have = false;
string best = "";
{
string cur = T + get(cnt);
if (cur[0] != '0')
{
if (!have || best > cur)
{
best = cur;
have = true;
}
}
}
string cur = "";
for (int i = 1; i < 10; ++i)
{
if (cnt[i] > 0)
{
cur += char(i + '0');
cnt[i]--;
break;
}
}
for (int i = 0; i <= 10; ++i)
{
string now = cur + T + get(cnt);
if (now[0] != '0')
{
if (!have || best > now)
{
best = now;
have = true;
}
}
if (i != 10)
{
cur += string(cnt[i], char(i + '0'));
cnt[i] = 0;
}
}
assert(have);
// cout << len << '\n';
puts(best.c_str());
exit(0);
}
return 0;
}