CodeVS1280 无限序列

http://codevs.cn/problem/1280/

题意:有一个无限序列:123456789101112……问第Ai位是什么数字。

线性的模拟会超时,因为这里的序列很有规律,所以可以考虑用数学方法来计算。

序列是由每个正整数依次连接的,但是正整数的位数有所不同,无法统一计算,因此应该先观察Ai位对应的正整数是几位的。

可以预先处理好小于某10的幂的所有正整数位数之和t[],以便根据的Ai和t[]大小关系来快速检索相应的位数。

得到位数后,根据Ai和t[]的差整除位数的结果计算出实际数字在当前位数的全部数字中的排名,并得到实际数字。

再根据Ai和t[]的差对位数取模的结果计算出第Ai位是实际数字中的第几位。

最后直接从实际数字中取出该位即可。

代码:

var
  a:array[0..14]of qword;
  t:array[0..15]of qword;
  n,i,j,ii:longint;
  k,x:qword;
begin
  t[0]:=1;
  for i:=1 to 15 do t[i]:=t[i-1]*10;
  a[0]:=0;
  for i:=1 to 14 do a[i]:=a[i-1]+9*t[i-1]*i;
  readln(n);
  for i:=1 to n do
    begin
      readln(k);
      if k<10 then
        begin
          writeln(k);
          break;
        end;
      for j:=14 downto 0 do
        if a[j]<k then break;
      x:=(k-a[j]-1) div (j+1)+t[j];
      for ii:=1 to j-(k-a[j]-1) mod (j+1) do
        x:=x div 10;
      writeln(x mod 10);
    end;
end.

你可能感兴趣的:(CodeVS1280 无限序列)