M2 C 咕咕東的奇妙序列

2021-10-05 03:38:44 字數 2047 閱讀 4412

題目

思路我覺得這道題非常難,一開始我完全找不到思路,只能盡量的騙分,後來問了別人才明白怎麼做。本題最核心的是兩個陣列,ret1和ret2。ret2[i]儲存的是從1到最大的i位數的子串的位數,做法是ret[i-1]+i位的所有數的位數,比如ret[2],即1-99的位數,就是1-9的位數(ret[i])加上10-99的位數,(99-9)*2([pow(10,i)-pow(10,i-1)]*i)。ret1[i]中儲存的的是從開始到i位數的最大數字開始出現時的位數,1-9為45,1-99為9045(方法是用等差數列求和的方式,這也是本題最核心的乙個演算法之一,另乙個是二分法)。方法不好說,舉個例子講一下9045是怎麼求的(即ret1[2]),先算上ret1[1],然後剩下的90×9(1-9九位數),然後乙個從10,1011,101112…,101112…99的等差數列求和即可。其他的實現我都給了詳細的注釋,就是乙個挺複雜的數學問題,但是易出錯。

**

#include

#include

#include

#include

#define inf 1e18

using

namespace std;

typedef

long

long ll;

ll ret1[10]

;

ll ret2[10]

;

ll ret

(ll t)

ll r2=0;

for(ll i =

1;i) r2+

=(t-

pow(

10,r1-1)

+1)*r1;

return r2;

}void

query()

}//我們以time為2為例,即從10-99

ll l =1;

ll r =

pow(

10,time)

-pow(10

, time-1)

;//10到99一共90個二位數

ll mid;

ll rt=

ret(

pow(

10, time -1)

);//1-10一共多少位

ll rnk=0;

//記錄mid=r+l/2的名次

//二分

while

(l <= r)

//可能在 mid-1,mid,mid+1組中

ll t1=

(mid-2)

*rt+

(mid-2)

*(mid-3)

*time/2;

//mid-1前面的位數

ll t2=

(mid-1)

*rt +

(mid-1)

*(mid-2)

*time/2;

//mid

ll t3= mid *rt +

(mid-1)

*mid*time/2;

//mid+1

if(k<=t2)

else

else

}for

(int j =

1; j <=

9; j++)}

ll m1=k/time;

//有幾個time位數

ll m2=k%time;

//k在time位數的第幾位

if(m2==0)

else}}

intmain()

ret1[0]

=0;for

(ll i =

1; i <=

8; i++

) ret1[9]

=inf;

query()

;return0;

}

C 咕咕東的奇妙序列

乙個序列 112123123412345123456 即第一部分包含1至1之間的所有數字,第二部分包含1至2之間的所有數字,第三部分包含1至3之間的所有數字,第i部分總是包含1至i之間的所有數字。求第k項數字是多少,注意第56項的數字為0.由分析可知 第一部分到第九部分相鄰部分的數字長度加一 第十部...

咕咕東的奇妙序列

題目 咕咕東的奇妙序列 題意 輸入 輸出 樣例 解題思路 這個題還是挺難的,主要是資料太大了,如果用字首和只能過前六個點,1e18不是鬧著玩的,陣列裝不下的 這裡說說我的思路 首先,我先搞個大小為8的陣列,存的是從1 10 i的數 如,陣列第乙個元素為 112123123412345 1234567...

咕咕東的奇妙序列 二分 數字模擬

poj 1019 number sequence 題目給出一種序列表示方式,可以表示為 1 12 123 1234 12345678910 序列不帶空格 也就是說序列可被分組,第 i 組包含的是1到 i 的所有數字。題目給出多個詢問要求每次得到序列中第 k 位的數字。注意 k 要能取到 10 18....