2019牛客暑期多校训练营(第十场)B Coffee Chicken(递归搜索)

题意:给出字符串 S 1 , S 2 S_1,S_2 S1,S2 S n = S n − 2 + S n − 1 S_n = S_n-2 + S_n-1 Sn=Sn2+Sn1,求第 n n n个字符串从第 k k k位开始的后10个字符串。其中 n &lt; = 500 , k &lt; m i n ( ∣ s ∣ , 1 0 12 ) ) n &lt;= 500, k &lt; min( |s|, 10^{12})) n<=500,k<min(s,1012))
思路:递归搜索,分为三种情况,最后在左区间,最后在右区间,最后在左右区间都有。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5 + 5;
const ll INF = 1e12;
ll f[100], n, k, t, cnt;
string s1 = "COFFEE";
string s2 = "CHICKEN";
void dfs(int rund, ll l, ll r) {
    if(rund == 1) {
        for(int i = l; i <= min(6ll, r); i++)
            putchar(s1[i - 1]);
        return;
    }
    if(rund == 2) {
        for(int i = l; i <= min(7ll, r); i++)
            putchar(s2[i - 1]);
        return;
    }
    if(f[rund - 2] > r) {//左
        dfs(rund - 2, l, r);
        return;
    }
    if(l > f[rund - 2]) {//右
        dfs(rund - 1, l - f[rund - 2], r - f[rund - 2]);
        return;
    }
    //左右都有,先递归打印左边保持顺序。
    dfs(rund - 2, l, f[rund - 2]);
    dfs(rund - 1, 1, r - f[rund - 2]);
}
int main() {
    f[1] = 6, f[2] = 7;
    for(cnt = 3;; cnt++) {
        f[cnt] = f[cnt - 2] + f[cnt - 1];
        if(f[cnt] > INF)
            break;
    }
    scanf("%lld", &t);
    while(t--) {
        scanf("%lld%lld", &n, &k);
        dfs(min(n, cnt), k, k + 9);
        puts("");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值