原题链接
标签:二分,BF暴力,数学
大概题意是说,有一个无穷长的数列,它的规律大致是“112123123412345123456…”,然后给你数字k,要你求出这个数列的第k项是哪个数字(0-9)
之前的第一反应是打表,但是好不容易解决了时间问题,结果内存不够,所以打表方法直接失效。
然后就问了llg,问了一下思路之后自己还打了半天才搞出来,其实自己也稍微想到了那一步了,就把数列分成每一个子数列,然后计算出每一个子数列的长度,把k划分到某一个子数列里头,再用字符串把它弄出来就可以了,但是之前没有想得很仔细,思路还不够清晰,主要是因为没有想到数列的递推,所以很难形象化,用到递推之后问题就差不多解决了,中途半天没有A的原因主要是没考虑清楚数组的范围和k的划分,最好在草稿本上写清楚再开始写代码。
附上源代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<string>
#include<queue>
#include<vector>
#include<map>
using namespace std;
FILE *stream;
#define ll long long
#define N 22001
#define zwh freopen_s(&stream,"in.txt","r",stdin), freopen_s(&stream,"out.txt","w",stdout);
int a[N], b[N];
//priority_queue <int, vector<int>, greater<int> > a;
ll f(ll x)
{
string s = to_string(x);
return s.size();
}
int main()
{
//zwh
string s;
ll n, k, ans;
cin >> n;
a[0] = b[0] = 0;
a[1] = 1, b[1] = 1;
for (ll i = 1; i < N-1; i++)
{
a[i + 1] = a[i] + f(i + 1);
b[i + 1] = a[i + 1] + b[i];
}
for (ll m = 0; m < n; m++)
{
cin >> k;
s = "";
for (ll i = 1; i < N; i++)
{
if (k == b[i])
{
for (ll j = 1; j <= i; j++)
{
s += to_string(j);
}
cout << s[k - b[i-1] - 1] << endl;
}
if (k > b[i] && k < b[i + 1])
{
//ans = i;
for (ll j = 1; j <= i+1; j++)
{
s += to_string(j);
}
cout << s[k - b[i] - 1] << endl;
break;
}
}
}
//system("pause");
return 0;
}