Comet OJ 双十一特惠简单版

题目描述

※ 简单版与困难版的唯一区别是粗體字部份和 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; 
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值