//by wyz
#include <stdio.h>
#include "math.h"
//获取到第i行字符串的长度
long long Get_Line(long long i)
{
long long sum = 0,pow_num = 0,m = i,min = 0;
while ((m /= 10) > 0)
{
pow_num++;
}
for (int j = 0; j < pow_num; j++)
{
sum += 9 *(j+1)*pow(10, j);
min += 9 * pow(10, j);
}
sum += (pow_num + 1)*(i-min);
return sum;
}
//获取第1到第i行字符串加起来的长度
long long Get_Sum(long long i)
{
long long j = i,Pow_Num = 0,Sum = 0;
while ((j /= 10) > 0)
{
Pow_Num++;
Sum += (pow(10, Pow_Num) - 1-(pow(10, Pow_Num-1) - 1))*
(Get_Line(pow(10, Pow_Num-1))+ Get_Line(pow(10, Pow_Num) - 1))/2;
}
return Sum += (i-pow(10, Pow_Num) + 1)*
(Get_Line(pow(10, Pow_Num )) + Get_Line(i)) / 2;
}
int main()
{
long long i,len = 0, Remain,Index = 0,Sub_Index = 0, N = 101, Left_Index = 1, Right_Index = 1;
char buf[25] = "";
scanf("%lld", &N);
Index = 1;
//找到大致范围
while (Get_Sum(Index) < N)
{
Index *= 2;
}
Left_Index = Index / 2;
Right_Index = Index;
//根据上一步结果,使用二分法精确找到第N个字符所在字符串行数
while (1)
{
len = Get_Sum((Left_Index + Right_Index) / 2);
if (len < N)
{
Left_Index = (Left_Index + Right_Index) / 2;
}
else if (len > N)
{
Right_Index = (Left_Index + Right_Index) / 2;
}
else
{
Index = (Left_Index + Right_Index) / 2;
break;
}
if (Left_Index + 1 == Right_Index)
{
if (Get_Sum(Left_Index) == N)
{
Index = Left_Index;
}
else
{
Index = Right_Index;
}
break;
}
}
Left_Index = 1;
Right_Index = Index;
//获取到第N个数字在这一列中的偏移
Remain = Get_Line(Index) - Get_Sum(Index) + N;
//根据偏移获取到第N位属于哪一个数字
while (1)
{
len = Get_Line((Left_Index + Right_Index) / 2);
if (len < Remain)
{
Left_Index = (Left_Index + Right_Index) / 2;
}
else if (len > Remain)
{
Right_Index = (Left_Index + Right_Index) / 2;
}
else
{
Sub_Index = (Left_Index + Right_Index) / 2;
break;
}
if (Left_Index + 1 == Right_Index)
{
if (Get_Line(Left_Index) == Remain)
{
Sub_Index = Left_Index;
}
else
{
Sub_Index = Right_Index;
}
break;
}
}
//printf("%lld\t%lld\t%lld\t%lld\t",Index, Get_Sum(Index-1),N, Get_Sum(Index));
//printf("%lld\t%lld\n", Remain - Get_Line(Sub_Index - 1), Sub_Index);
//将这个数字转化为字符串后显示出来
sprintf(buf, "%lld", Sub_Index);
//Get_Line(Sub_Index - 1)是上一行的长度,这样可以算出来N是最后一个数字的第几位。
printf("%c", buf[Remain - Get_Line(Sub_Index - 1) - 1]);
}
效率应该还行,c写的是100%,直接拿去c++也是100%。