Comet OJ - Contest #15

https://cometoj.com/contest/79/problem/D?problem_id=4219

题目描述

※ 简单版与困难版的唯一区别是粗体字部份和 $v$ 的数据范围。

在双 11 时,心慧精品店有个特别的折价活动如下:

首先,我们定义一个正整数为"好的"当且仅当此数仅由数字 1 构成,举例来说 11111111111 都是「好的」,但 10123321 都是「不好的」。

接着,若一个商品原价为 x,若顾客能把 x 表示为 k 个「好的」数字,那么此顾客就能用 k 元买下它。

小月在心慧精品店里看上了一件原价为 v 的商品,请输出小月最少需要花多少钱才能买下此商品。

 题解

因为求由构成数x的最小数字,将问题转换为 x*9 由 9, 99 构成的数,令 u = 9*x, ans为最小个数,所以 u + ans 的 10 的幂和,so u + x 是10的倍数且位数和dig_num <= ans且u + x > 10*x,

然后暴力枚举瞎搞就好了

#include<bits/stdc++.h>
#define rep(i, n) for(int i=0;i!=n;++i)
#define per(i, n) for(int i=n-1;i>=0;--i)
#define Rep(i, sta, n) for(int i=sta;i!=n;++i)
#define rep1(i, n) for(int i=1;i<=n;++i)
#define per1(i, n) for(int i=n;i>=1;--i)
#define Rep1(i, sta, n) for(int i=sta;i<=n;++i)
#define L k<<1
#define R k<<1|1
#define inf (0x3f3f3f3f)
#define llinf (1e18)
#define mid (tree[k].l+tree[k].r)>>1
#define ALL(A) A.begin(),A.end()
#define SIZE(A) ((int)A.size())
typedef long long i64;
using namespace std;
const int MAX_LEN = 1000010;
char str[MAX_LEN];
void solve()
{
    str[0] = 0; scanf("%s",str+1);
    int len = strlen(str+1),dig_num = 0;
    for(int i=1;i<=len;++i)
        str[i] = (str[i] - '0')*9;
    for(int i=len;i>0;--i){
        str[i-1] += str[i] / 10;
        str[i] %= 10;
        dig_num += str[i];
    }
    dig_num += str[0];
    int ans = 10 - str[len];
    str[len] += ans;
    dig_num += ans;
    while(true){
        for(int i=len;i>0;--i){
            if(str[i] >= 10){
                dig_num -= 9;
                str[i] -= 10;
                ++str[i-1];
            }else
                break;
        }
        if(dig_num <= ans){
            cout << ans <<'\n';
            return;
        }
        ans += 10;
        dig_num += 10;
        str[len] += 10;
    }
}
int main() {
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int T;  scanf("%d",&T);
    while(T--)  solve();    
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/newstartCY/p/11962004.html