1. 程式人生 > >【AtCoder】AGC011 E - Increasing Numbers

【AtCoder】AGC011 E - Increasing Numbers

就是 size () stdin cto clear -- UC cond

題解

題是真的好,我是真的不會做
智商本還是要多開啊QwQ

我們發現一個非下降的數字一定可以用不超過九個1111111111...1111表示

那麽我們可以得到這樣的一個式子,假如我們用了k個數,那麽最多的話可以是這樣的
\(N = \sum_{i = 1}^{9k} (10^{r_i} - 1) / 9\)
\(9N + 9k = \sum_{i = 1}^{9k} 10^{r_{i}}\)

我們只要每次計算出9N + 9 ,9N + 18...,然後看看十進制下每一位的數字和有沒有超過9k,直接加的話最壞情況是一次操作\(O(L)\)的,但是大家應該都有種直覺總的操作就是\(O(L)\)的……就是勢能分析啦,不太會證,就是一次長的進位過後之後不會再進位了。。。

復雜度\(O(lg N)\)

代碼

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <cmath>
#include <bitset>
#include <queue>
#define enter putchar(‘\n‘)
#define space putchar(‘ ‘)
//#define ivorysi
#define pb push_back #define mo 974711 #define pii pair<int,int> #define mp make_pair #define fi first #define se second #define MAXN 200005 #define eps 1e-12 using namespace std; typedef long long int64; typedef double db; template<class T> void read(T &res) { res = 0;char c = getchar();T f = 1
; while(c < ‘0‘ || c > ‘9‘) { if(c == ‘-‘) f = -1; c = getchar(); } while(c >= ‘0‘ && c <= ‘9‘) { res = res * 10 - ‘0‘ + c; c = getchar(); } res = res * f; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar(‘-‘);} if(x >= 10) out(x / 10); putchar(‘0‘ + x % 10); } struct Bignum { vector<int> v; int sum; Bignum operator = (string s) { v.clear(); sum = 0; for(int i = s.length() - 1 ; i >= 0 ; --i) { v.pb(s[i] - ‘0‘); sum += s[i] - ‘0‘; } return *this; } friend Bignum operator * (const Bignum &a,const int b) { int s = a.v.size(); Bignum c;c.v.clear(); for(int i = 0 ; i <= s ; ++i) c.v.pb(0); int g = 0; for(int i = 0 ; i < s ; ++i) { int x = a.v[i] * b + g; c.v[i] = x % 10; g = x / 10; } if(g) c.v[s] = g; for(int i = s ; i > 0 ; --i) { if(c.v[i] == 0) c.v.pop_back(); else break; } c.sum = 0;s = c.v.size(); for(int i = 0 ; i < s ; ++i) c.sum += c.v[i]; return c; } }A; string s; void Solve() { cin>>s; A = s; A = A * 9; int ans = 0; while(1) { int s = A.v.size(); int g = 9; for(int i = 0 ; i < s ; ++i) { if(!g) break; A.sum -= A.v[i]; int x = A.v[i] + g; A.v[i] = x % 10; A.sum += A.v[i]; g = x / 10; } if(g) A.v.pb(g),A.sum += g; ++ans; if(ans * 9 >= A.sum) break; } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }

【AtCoder】AGC011 E - Increasing Numbers