AGC011 E Increasing Numbers
阿新 • • 發佈:2018-12-12
題意
定義一個數是上升的,當其每個數位上的數不小於比它數位高的數 比如11233 然後給你一個數N() 求它最少能拆成幾個上升的數的和
題解
首先有幾個性質需要發現 第一個是對於一個上升的數,它一定可以寫成不超過9個1111111…結構的數的和 也即是說,他一定能寫成恰好9個結構為的和 假如說答案為k,那麼 移項,可有 可以證明的是,然而我覺得我講不清楚 是上述等式成立的充要條件 所以我們判斷這個即可 又由於,我又證不來了,比較顯然的是,答案應該是L級別的 所以我們從小到大列舉k即可 時間複雜度
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int L=500005,M=500005;
typedef long long ll;
const int base=10;
struct BigInt{
int a[M];
int len;
BigInt(){}
BigInt(char *s){
memset(a,0,sizeof a);
len=strlen(s+1);
for(int i=len;i>=1;i--)
a[i]=s[len-i+1]-'0';
}
};
int ans;
void operator +=(BigInt& x,int y){
x.a[1]+=y;
ans+=y;
for(int i=1;i<=x.len;i++){
if(x.a[i]>=base){
if(i==x.len)
x.len++;
ans-=x.a[i];
ans-=x.a[i+1];
x.a[i+1]++;
x.a[i]-=base;
ans+=x.a[i];
ans+=x.a[i+1];
}
else
break;
}
}
BigInt operator *(BigInt x,int y){
int r=0;
for(int i=1;i<=x.len;i++){
x.a[i]*=y;
x.a[i]+=r;
if(x.a[i]>=base){
r=x.a[i]/base;
x.a[i]%=base;
}
else
r=0;
}
x.len++;
x.a[x.len]+=r;
while(x.len>0&&x.a[x.len]==0)
x.len--;
return x;
}
int sum(BigInt x){
int res=0;
for(int i=1;i<=x.len;i++){
res+=x.a[i];
}
return res;
}
char s[L];
int main()
{
//freopen("z.in","r",stdin);
scanf("%s",s+1);
BigInt x(s);
x=x*9;
ans=sum(x);
for(int k=1;;k++){
x+=9;
//if(k%10000==0)
// puts("!");
if(ans<=9*k){
printf("%d\n",k);
return 0;
}
}
}