Sum of Digits
.
.
题意:给出s1、s2,问最小的数使得每位之和为s1,每位平方之和为s2,位数不超过100。
.
.
解法:dp,因为不超过100位,用[900][8100]来记录到达当前状态最小的位数,以及同样位数尽量放小的值,先把全部预处理好即可。
.
.
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
int sqr(int x) {
return x*x;
}
int f[901][8101];
int b[901][8101], a[10], x1, y1, x, y;
int main() {
memset(f, 255, sizeof(f));
memset(b, 255, sizeof(b));
b[0][0] = 0;
f[0][0] = 0;
for (int i = 1; i <= 900; i++)
for (int j = 1; j <= 8100; j++)
for (int k = 1; k <= 9; k++) if (k <= i && k*k <= j) {
if (f[i-k][j-k*k] != -1) {
if (b[i][j] == -1 || b[i-k][j-k*k]+1 < b[i][j]) {
f[i][j] = (i-k)*10000+(j-k*k);
b[i][j] = b[i-k][j-k*k]+1;
}
}
}
int tt;
cin >> tt;
while (tt--) {
scanf("%d %d", &x, &y);
if (x > 900 || y > 8100) {
printf("No solution\n");
continue;
}
if (f[x][y] == -1) {
printf("No solution\n");
continue;
}
if (b[x][y] > 100) {
printf("No solution\n");
continue;
}
memset(a, 0, sizeof(a));
while (1) {
if (x == 0 && y == 0) break;
a[x-f[x][y]/10000]++;
x1 = x; y1 = y;
x = x-(x1-f[x1][y1]/10000);
y = y-sqr(x1-f[x1][y1]/10000);
}
for (int i = 1; i <= 9; i++)
for (int j = 1; j <= a[i]; j++) printf("%d", i);
printf("\n");
}
}