题目链接:
题目大意:
q组测试,每组给一个初始字符串 s0 , 定义字符串 si= “What are you doing while sending “ fi − 1 ”? Are you busy? Will you send “ fi − 1 ”?” 问 Sn 的第k个字母是什么 。
数据范围:
1≤q≤10
1≤n≤105
1≤k≤1018
解题思路:
思路就是看k在哪一段, 一段一段的去判断, 当位于 si−1 段的时候, 就递归一下查找。
AC代码:
/********************************************
*Author* :ZZZZone
*Created Time* : 六 12/ 2 21:53:02 2017
* Ended Time* : 二 12/ 5 16:12:47 2017
*********************************************/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <stack>
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 1e18;
const int MaxN = 1e5;
const string s0 = "What are you doing at the end of the world? Are you busy? Will you save us?";
const string s1 = "What are you doing while sending \"";
const string s2 = "\"? Are you busy? Will you send \"";
const string s3 = "\"?";
const LL len0 = s0.size(), len1 = s1.size(), len2 = s2.size(), len3 = s3.size();
LL sum[MaxN + 5];
char solve(LL k, int n){
if(n == 0){
if(k >= 1 && k <= len0) return s0[k - 1];
else return '.';
}
if(k <= len1) return s1[k - 1];
k -= len1;
if(k <= sum[n - 1] || sum[n - 1] == 0) return solve(k, n - 1);
k -= sum[n - 1];
if(k <= len2) return s2[k - 1];
k -= len2;
if(k <= sum[n - 1] || sum[n - 1] == 0) return solve(k, n - 1);
k -= sum[n - 1];
if(k <= len3) return s3[k - 1];
return '.';
}
int main()
{
int q, n;
LL k;
sum[0] = len0;
LL tot = len1 + len2 + len3;
for(int i = 1; sum[i - 1] <= INF; i++)
sum[i] = tot + sum[i - 1] * 2LL;
scanf("%d", &q);
while(q--){
scanf("%d %lld", &n, &k);
printf("%c", solve(k, n));
}
return 0;
}