基准时间限制: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;
}