题目链接:https://codeforces.com/contest/1567/problem/D
分析
先想一下如果我们将
10
10
10拆分成了
9
+
1
9+1
9+1,那么最后损失了
1
1
1,因为
1
0
(
11
)
=
11
10_{(11)} = 11
10(11)=11而
(
9
+
1
)
11
=
10
(9 + 1)_{11} = 10
(9+1)11=10。
如何拆分一个数不会造成损失:
- 将每位上的数单独拆分出来,例如 1023 = 1000 + 20 + 3 1023=1000+20+3 1023=1000+20+3;
- 在一个位数上进行拆分(位数相同),例如 60 = 10 + 50 60=10+50 60=10+50。
那么我们只要优先无损失地进行拆分。
如果不能无损失地进行拆分,就选择一个最小的大于
1
1
1的数进行有损失拆分即可。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,s;
vector<int> ans, a, b;
int check(int x)
{
while(x)
{
int tmp = x % 10;
if(tmp > 0) return tmp;
else x /= 10;
}
return 0;
}
int length(int x)
{
int res = 0;
while(x)
{
res++;
x /= 10;
}
return res;
}
int main()
{
int T = 1;
scanf("%d",&T);
while(T--)
{
ans.clear();
scanf("%d%d",&s,&n);
int x = s;
int len = 0;
while(x)
{
if(x % 10) len++;
x /= 10;
}
if(n <= len)
{
int tmp = 10;
for(int i=1;i<n;i++)
{
if(s % tmp) ans.push_back(s % tmp);
else i--;
s -= s % tmp;
tmp *= 10;
}
ans.push_back(s);
}
else
{
a.clear();
b.clear();
int tmp = 10;
for(int i=1;i<len;i++)
{
if(s % tmp) a.push_back(s % tmp);
else i--;
s -= s % tmp;
tmp *= 10;
}
a.push_back(s);
int now = len;
while(now < n)
{
int flag = 0;
for(int i=0;i<a.size();i++) if(check(a[i]) > 1) flag = 1;
if(flag == 1)
{
int f = 0;
for(int i=0;i<a.size();i++)
{
int t = check(a[i]);
if(t > 1 && f == 0)
{
f = 1;
b.push_back((t - 1) * pow(10, length(a[i]) - 1));
b.push_back(pow(10, length(a[i]) - 1));
now++;
}
else b.push_back(a[i]);
}
}
else
{
sort(a.begin(), a.end());
int f = 0;
for(int i=0;i<a.size();i++)
{
if(a[i] > 1 && f == 0)
{
f = 1;
b.push_back(9 * pow(10, length(a[i]) - 2));
b.push_back(pow(10, length(a[i]) - 2));
now++;
}
else b.push_back(a[i]);
}
}
a.clear();
for(int i=0;i<b.size();i++) a.push_back(b[i]);
b.clear();
}
for(int i=0;i<a.size();i++) ans.push_back(a[i]);
}
for(int i=0;i<ans.size();i++) printf("%d ",ans[i]);
printf("\n");
}
return 0;
}