题目描述
※ 简单版与困难版的唯一区别是粗體字部份和 vv 的数据范围。
在双 11 时,心慧精品店有个特别的折价活动如下:
首先,我们定义一个正整数为"好的"当且仅当此数仅由数字 1 构成,举例来说 1, 11, 111, 11111 都是「好的」,但 10、123、321 都是「不好的」。
接着,若一个商品原价为 xx,若顾客能把 xx 表示为 kk 个「好的」数字,那么此顾客就能用 kk 元买下它。
小月在心慧精品店里看上了一件原价为 vv 的商品,但小月的预算只有 99 元,请问小月能否在预算内买下此件商品,若可以请输出小月最少需要花多少钱才能买下此商品,否则输出 Impossible。
输入描述
第一行有一个正整数 TT 代表一个文件有几组数据。
每个数据各占一行,该行包含一个正整数 vv,代表小月看上的商品的价钱。
1 \le T \le 101≤T≤10
1 \le v \le 10^91≤v≤10
9
输出描述
每个数据输出一行,若小月能在预算内买下该商品,输出一个整数代表买下该商品最少需要的钱,否则输出 Impossible。
样例输入 1
3
9
10
1133
样例输出 1
9
Impossible
3
样例解释 1
对于第一组数据,把 99 拆成许多「好的」数的和只有 11 种拆法,也就是拆成 99 个 11 的和,故小月只能按照原价买下它。
对于第二组数据,把 1010 拆成许多「好的」数的和只有 11 种拆法,也就是拆成 1010 个 11 的和,1010 已经超过小月的预算,所以此数据要输出 Impossible。
对于第三组数据,11331133 可以拆成 1111+11+111111+11+11,只需要 33 个「好的」数字,这也是最佳的拆法,故答案为 33。
分析: 不超过10^9的【好的】数只有1,11,111…111111111(9个1) 这九种,
我们可以用DFS将所有的情况都尝试一下,
#include "cstdio"
#include "cstring"
const int MAX_V=1000000000;//最大数10^9
int n; /*最少个数*/
// x:当前处理的数据,ones: 1的个数, need:已经使用 '好'数 的数目
void dfs(int x,int ones,int need)
{
if(x<0||need>=n) /*如果使用过'好'的个数大于n,没有必要搜索下去了*/
return;
if(!x) /*x==0,此时已经拆分完毕*/
{
if(n>need) /*尝试更新n的值*/
n=need;
return;
}
if(ones>=MAX_V) /*控制 '好'数的范围*/
return;
dfs(x-ones,ones,need+1);/*当前ones可以使用,need数目加一,在本次ones的情况下在此尝试*/
dfs(x,ones*10+1,need); /*当前ones不使用,need数目不变,增大ones继续尝试*/
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int v;
scanf("%d",&v);
n=10; //初始为不可能的情况,等下用于判断
dfs(v,1,0);
if(n==10)/*如果搜索完后n的数目没有更新,说明不可能*/
puts("Impossible");
else
printf("%d\n",n);
}
return 0;
}