9269:Big String超级字符串
-
总时间限制:
- 10000ms 单个测试点时间限制:
- 1000ms 内存限制:
- 131072kB
-
描述
-
fish在无数次oi竞赛的狱炼之后,悟出一个真理,往往越容易的题目,陷阱越深。由此,fish创作了这道题目。
fish首先给出两个短串A=’4567’ (4个字符), B=’123’(3个字符)。反复进行如下的操作得到一个长串C。
(1)C=B+A (例如:A=’4567’ ,B=’123’ C=B+A=’1234567’)
(2)A=B B=C (上述例子 A=’123’ B=’1234567’)
请你编程找出这个长串的第n个字符。
输入
-
第一行包含一个整数 n (1<=n<=10^9)
输出
-
仅一行,包含一个字符,表示这个长串的第n个字符。
样例输入
-
9
样例输出
-
2
显然这数据范围是很尴尬的=。=,在纸上模拟一下:
A0=4567 B0=123 -> C1=1234567
A1=B0=123 B1=C1=1234567 ->C2=A1+B1=1234567123
A2=B1=C1=1234567 B2=C2=1234567123 ->C3=A2+B2=C1+C2=12345671234567123
A3=B2=C2=1234567123 B3=C3=12345671234567123 -> C4=A3+B3=C2+C3
........
其实应该已经发现规律了:
(1)C[i]=C[i-1]+C[i-2](i>=3)
(2)每一位我们都可以在1234567这个字串中找到
(3)每一个新子串都可以看做是1234567或它的子串组成的
那么我们只需要知道第n位是1234567 中的第几位,而对这个那么长的子串究竟是什么根本没用=。=
所以我们根本没必要存具体的子串只需要存它一共有几位就行了
即:f[i]=f[i-1]+f[i-2](i>=3)
f[1]=3;f[2]=7
所以我们只需要知道第n位是在什么时候产生的就行了,
比如说第16位,由于16>10 并且16<17 所以它是在产生到第17位的时候才知道的,
那么我们对前10位完全不感兴趣,直接16-10=6,因为它是在组成该大子串的第二个小子串中,
那么同理我们只需要知道第二个小子串中的第6位是在1234567中的第几位
.......
一直推下去一直到n<=7,即可以确定它是在1234567中的具体的位置
输出该位的数字(字符)即可
var
f :array[0..45] of int64;
n :int64;
i :longint;
s :string;
begin
read(n);s:='1234567';
f[1]:=3;f[2]:=7;
for i:=3 to 42 do f[i]:=f[i-1]+f[i-2];
for i:=1 to 42 do
if (n<=f[i+1]) and (n>f[i]) then break;
//
while (n>7) and (i>=1) do
begin
while (n<=f[i]) and (i>=1) do dec(i);
dec(n,f[i]);
end;
writeln(s[n]);
end.
——by Eirlys
转载请注明出处=w=