给你四个字符串
string a = "What are you doing at the end of the world? Are you busy? Will you save us?";
string b = "What are you doing while sending \"";
string c = "\"? Are you busy? Will you send \"";
string d = "\"?";
有一个字符串数组
规律为如下:
f[0] = a;
f[n] = b + f[n-1] + c + f[n-1] + d;
现在给你一个n和k
要你求出f[n] 的第k个字符
如果k > f[n]的长度 就返回 '.'
题解:
开一个num数组,num[i] 表示 f[i] 的长度
由于num数组到后面已经超出了long long的范围了
所以我们只要求到num[55] , num[56]已经爆了long long
后面的数组赋值给一个很大的数字就行 例如LLONG_MAX long long 范围的最大值
然后通过递归 把在f[n]的第k个位置 推到 在f[0]原来的位置 然后输出答案即可
#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
#define ll long long
string a = "What are you doing at the end of the world? Are you busy? Will you save us?";
string b = "What are you doing while sending \"";
string c = "\"? Are you busy? Will you send \"";
string d = "\"?";
//string f1 = b + a + c + a + d;
int lena = a.size();
int lenb = b.size();
int lenc = c.size();
int lend = d.size();
ll num[maxn];
char ans;
ll nn, kk;
char dfs(int n, ll k) {
if(k >= num[n]){
return '.';
}
if(n == 0) {
return a[k];
}
if(k < lenb) {
return b[k];
}
k -= lenb;
if(k < num[n-1]) {
return dfs(n-1, k);
}
k -= num[n-1];
if(k < lenc) {
return c[k];
}
k -= lenc;
if(k < num[n-1]) {
return dfs(n-1, k);
}
k-=num[n-1];
if(k < lend) {
return d[k];
}
}
int main() {
num[0] = lena;
for(int i = 1; i <= 55; i++) {
num[i] = lenb + lenc + lend + 2*num[i-1];
cout<<num[i]<<endl;
}
for(int i = 56; i <= 100000; i++) {
num[i] = LLONG_MAX;
}
// cout<<LLONG_MAX<<endl;
//9223372036854775807LL
int q;
cin>>q;
while(q--) {
cin>>nn>>kk;
ans = dfs(nn, kk-1);
printf("%c", ans);
}
cout<<endl;
return 0;
}