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

2021-10-04 20:50:29 字數 2139 閱讀 5928

poj 1019 number sequence

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

首先說明題目序列的含義和詢問方式,k的最大取值就是序列的最長長度,並且本題中要按照 k 位來查詢,這就使得序列中兩位以上的數字很難處理,也就是要將序列分為若干個大組,每個大組包含多個小組。大組可以按照1~9,10~99,100~999,…這樣的方法來分,因為每一小組內最大數字的位數相同,同時這樣分組可以降低之後定位是的時間複雜度,這一點對於10^18的資料量非常關鍵。

分好組後,我們需要得到每一大組及其之前大組所包含的元素總和,以便定位 k 所在的大組,這一點可以用等差數列的求和思路來做。同時我們還要能確定每一大組的小組內,不同位數數字的分界點,以便找到 k 對應的位置所對應數字的位數,方便從這個數字中取一位(思路複雜,反覆琢磨)。需要用到二分查詢的地方就是要去除 k 對應大組內所有在 k 對應小組之前的小組的元素數。之後由上面說過的方法,再去除 k 對應小組內所有位數小於 k 對應數字位數的元素和,這樣 k 表示的值就是 k 對應數字的從左往右第 k 位。之後只要找到這一位就可以了,注意細心。

本題在csp模擬時的資料量十分龐大,要遠大於poj上的情況,因此poj上的題解是不能直接使用的。據我觀察,poj上的大多題解是直接按照小組來存貯組內元素個數,然後尋找 k 對應的小組,這樣自然是比直接暴力尋找快一些,但還是達不到本次題目要求,所以必須要採用兩次分組。但是兩次分組更加繁瑣易錯,一定要十分細緻準確理解陣列的含義和上述確定數字的方法。

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define maxn 10005

#define inf 1e9

using

namespace std;

ll q,l,r,k,t,mid,l,r,cnt;

ll a[maxn]

,b[maxn]

,c[maxn]

,d[maxn]

;voidin(

long

long

&x)while

(c<=

'9'&&c>=

'0')

x*=y;}

void

out(

long

long x)

if(x>9)

out(x/10)

;putchar

(x%10

+'0');

}void

init()

k =9;

for(ll i =

1; i <=9;

++i)

k =9;

for(ll i =

1; i <=9;

++i)

}bool

check

(ll x)

//確定x是否是k之前包含的該大段內的組數

ll sum

(ll x)

//減去k之前包含的該大段內的組數的總元素數

void

sol(ll x)

//將連續數字分解

d[++cnt]

= x %10;

}int

main()

} k -

= a[t-1]

; l =

1; r =

1e9;

while

(l < r)

k -=sum

(l-1);

for(ll i =

1; i <=9;

++i)

} k -

= b[t-1]

; l = k / t;

r = k % t;

//位數相同的第l個數字倒數第r位

if(r ==0)

else

}return0;

}

咕咕東的奇妙序列

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

C 咕咕東的奇妙序列

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

M2 C 咕咕東的奇妙序列

題目 思路我覺得這道題非常難,一開始我完全找不到思路,只能盡量的騙分,後來問了別人才明白怎麼做。本題最核心的是兩個陣列,ret1和ret2。ret2 i 儲存的是從1到最大的i位數的子串的位數,做法是ret i 1 i位的所有數的位數,比如ret 2 即1 99的位數,就是1 9的位數 ret i ...