1658. Sum of Digits
Time limit: 2.0 second
Memory limit: 64 MB
Memory limit: 64 MB
Petka thought of a positive integer
n and reported to Chapaev the sum of its digits and the sum of its squared digits. Chapaev scratched his head and said: “Well, Petka, I won't find just your number, but I can find the smallest fitting number.” Can you do the same?
Input
The first line contains the number of test cases
t (no more than 10000). In each of the following
t lines there are numbers
s
1and
s
2 (1 ≤
s
1,
s
2 ≤ 10000) separated by a space. They are the sum of digits and the sum of squared digits of the number
n.
Output
For each test case, output in a separate line the smallest fitting number
n, or “No solution” if there is no such number or if it contains more than 100 digits.
Sample
input | output |
---|---|
4 9 81 12 9 6 10 7 9 | 9 No solution 1122 111112 |
Problem Author: Vladimir Yakovlev (idea by Stanislav Vasilyev)
Problem Source: NEERC 2008, Eastern subregion quarterfinals
Problem Source: NEERC 2008, Eastern subregion quarterfinals
Difficulty: 247
Printable version
Submit solution
Discussion (21)
All submissions (10761) All accepted submissions (2149) Solutions rating (1301)
题目:要求输出最小的由1-9组成的数字, 每一位和为s1, 每一位平方和为s2,的最小数子;
分析:dp求种类数也海星,但要是输出就要看一下啦,幸好只有900*8100中状态,递推就可以,然后回溯记录一下每一位的值,再排序就可以啦!!!
dp[i][j] : 表示数位和为i,数位平方和为j的最小位数;
dp[i][j] = min(dp[i][j], dp[i - k][j - k*k]);(1<= k <= 9);
v[i][j] : 记录k,方便回溯找到答案;
代码:
#include<bits/stdc++.h>
#include<vector>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1000;
const int maxm = 9000;
/*
dp[i][j] : 表示数位和为i,数位平方和为j的最小位数;
dp[i][j] = min(dp[i][j], dp[i - k][j - k*k]);(1<= k <= 9);
v[i][j] : 记录k,方便回溯找到答案;
*/
int t, s1, s2, dp[maxn][maxm], v[maxn][maxm];
vector<int>ans;
void init()
{
memset(dp, INF, sizeof(dp));
dp[0][0] = 0;
for(int i = 1; i <= 900; i++)
{
for(int j = 1; j <= 8100; j++)
{
for(int k = 1; k <= 9; k++)
{
int x = i - k, y = j - k*k;
if(x >= 0&& y>= 0){
if(dp[i][j] > dp[x][y] + 1)
{
dp[i][j] = dp[x][y] + 1;
v[i][j] = k;
}
}
}
}
}
}
int main()
{
init();
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &s1, &s2);
if(s1>900||s2>8100||dp[s1][s2] > 100)
{
puts("No solution");
continue;
}
ans.clear();
int x = s1, y = s2;
while(x && y)
{
ans.push_back(v[x][y]);
int k = v[x][y];
x -= k;
y -= k*k;
}
sort(ans.begin(), ans.end());
for(auto &v : ans) printf("%d", v);
printf("\n");
}
return 0;
}