Codeforces Round #449 (Div. 2) C. Nephren gives a riddle 递归

http://codeforces.com/contest/897/problem/C


又是正视了自己的递归水平,55555。

题意:递归又递归的字符串   下面q个询问,第fn个字符串的第k个字符是啥,如果fn没k这么长就是.


做法:递归长度,n很大,先处理n,如果n k一直很大,可以先判断他是在哪个范围,至少得突破最左边的边缘区,就是34那一块,所以

先不断减小n,k达到可以处理的阶段。

另外就是不断递归了


#include<bits/stdc++.h>
using namespace std;
string p = "What are you doing at the end of the world? Are you busy? Will you save us?", q = "What are you doing while sending \"", r = "\"? Are you busy? Will you send \"", s = "\"?";
long long x[100001], y, z, t;
char f(long long a, long long b)
{
	if(b>=x[a]) return '.';
	if(a == 0) return p[b];
	if(b<q.size()) return q[b];
	b-=q.size();
	if(b<x[a-1]) return f(a-1, b);
	b-=x[a-1];
	if(b<r.size()) return r[b];
	b-=r.size();
	if(b<x[a-1]) return f(a-1, b);
	b-=x[a-1];
	if(b<s.size()) return s[b];
	return '.';
}
int main(void)
{
	x[0] = p.size();
	for(int i=1;i<=55;i++) x[i] = 2*x[i-1]+q.size()+r.size()+s.size();
	for(int i=56;i<=100000;i++) x[i] = LLONG_MAX;
	for(cin>>t;t--;) cin>>y>>z, cout<<f(y, z-1);
}


f0 = "What are you doing at the end of the world? Are you busy? Will you save us?"
p1 = "What are you doing while sending \""
p2 = "\"? Are you busy? Will you send \""
p3 = "\"?"
f = []
def dfs(n, k):
    if k > f[n]: return '.'
    if n == 0: return f0[k-1]
    if k <= 34: return p1[k-1]
    if k <= f[n-1] + 34: return dfs(n - 1, k - 34)
    if k <= f[n-1] + 66: return p2[k - f[n-1] - 34 - 1]
    if k <= 2 * f[n-1] + 66: return dfs(n - 1, k - f[n-1] - 66)
    return p3[k - f[n-1] * 2 - 66 - 1]

f.append(75)
cnt = 0
for i in range(0, 100):
    f.append(f[cnt] * 2 + 68)
    cnt += 1

def solve():
    n, k =map(int, input().split(' '))
    while n > 56 and k > 34:
        k -= 34
        n -= 1
    if k <= 34:
        print(p1[k - 1], end='')
    else:
        print(dfs(n, k), end='')
def main():
    case = 1
    case = int(input())
    for case in range(case):
        solve()

main()



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值