51Nod-1385 凑数字(贪心)

1385 凑数字 

基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题

 收藏

 关注

给定一个n,要求找出一个最短的字符串S,使得所有1到n的整数都是S的子序列。

比如n=10,那么S=”1234056789”的时候,是满足条件的。这个时候S的长度是10。

 

现在给出一个n,要求输出最短S的长度。

Input

第1行:给出一个整数n (1<=n<=1e10000)。

Output

输出最短S的长度

Input示例

10

Output示例

10

题解:

设长度为len,那么长度为len-1的数字全部都要取到,需要10*(len-1)个数字,并且很容易想到这些数字是以0123456789这样排列的。

然后考虑长度为len的数字,假设最高位是x,那么最高位一定要取到[1,x-1],需要x-1个数字,接着就是考虑是否要取到x。

假设y是从最高位往右找第一个不等于x的数。

如果y<x,那么最高位可以不取到x,例如328,我们这样排列:1298765432100123456789,发现仍然可以取到328

如果y>x,则最高位一定要取到x

#include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<string>
#include<cstring>
#include<map>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define x first
#define y second
#define rep(i,a,b) for(int i=a;i<(b);++i)
#define per(i,a,b) for(int i=a-1;i>=(b);--i)
#define fuck(x) cout<<'['<<#x<<' '<<(x)<<']'
#define add(x,y) x=((x)+(y)>=mod)?(x)+(y)-mod:(x)+(y)
#define sub(x,y) x=((x)-(y)<0)?(x)-(y)+mod:(x)-(y)
#define clr(a,b) memset(a,b,sizeof(a))
#define eps 1e-10
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> VI;
typedef pair<int, int> PII;

const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
const int mod = 1e9 + 7;
const int MX = 1e5 + 5;

char s[MX];

int main() {
#ifdef local
    freopen("in.txt", "r", stdin);
#endif // local
    cin >> s + 1;
    int n = strlen(s + 1);
    if(n == 1) return printf("%d\n", s[1] - '0') * 0;
    int ans = (n - 1) * 10 + s[1] - '1', mark = 1;
    rep(i, 1, n) {
        if(s[i] > s[i + 1]) {mark = 0; break;}
        if(s[i] < s[i + 1]) break;
    }
    if(mark) ans++;
    printf("%d\n", ans);
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值