zoukankan      html  css  js  c++  java
  • 2019牛客暑期多校训练营(第十场)B-Coffee Chicken

    >传送门<

    题意:S(1)="COFFEE",S(2)="CHICKEN" ,S(n) = S(n−2)+S(n−1),请输出 S(n) 中从第 k 个字符开始的10个字符(若不足10个输出到末尾即可),(1≤n≤500,1≤k≤min(|S(n)|,1012)

    思路:那会好多人过了这题,就尝试去写了一下,然而我处理的是区间,答案输出是对的,但是莫名其妙的段错误,可能用区间处理递归太多了吧,后来看到xjl学姐过了,她用for循环模拟的递归,是对十个位置上每个字符进行处理,仔细想想,这样写的确比我的要好,太弱了,连递归都写不好~T_T 以下来自官方题解

    f(i) 表示 S(i) 的长度,f(i) = f(i−2) + f(i−1).

    递归调用 solve(n,k) 表示 S(n) 的第 k 个字符,

    n≤2 直接返回答案,

    n>2 时,若 k>f(i−2),调用 solve(n−1,k−f(n−2))否则调用 solve(n−2,k).

    注意特判 k>f(n).

    Code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll t, n, k;
    ll f[58] = {0,6,7};
    char s1[10] = "COFFEE", s2[10] = "CHICKEN";
    void dfs(int n, ll k){
        if(k>f[n]) return;
        if(n==1) printf("%c", s1[k-1]);
        else if(n==2) printf("%c", s2[k-1]);
        else {
            if(k>f[n-2]) dfs(n-1,k-f[n-2]);
            else dfs(n-2,k);
        }
    }
    int main()
    {
        for(int i=3;i<=57;i++) f[i]=f[i-1]+f[i-2];
        //for (int i = 1; i <= 57; i++) printf("%lld ", f[i]);
        scanf("%d",&t);
        while(t--){
            scanf("%d%lld", &n, &k);
            if(n>57)
                if(n&1) for(int i=0;i<10;i++) dfs(57,k+i);
                else for(int i=0;i<10;i++) dfs(56,k+i);
            else
                for(int i=0;i<10;i++) dfs(n,k+i);
            printf("
    ");
        }
        return 0;
    }
    View Code

    至于为什么这里n只用计算到57,仔细看题目就知道k最大只能到1e12,因此n大到一定程度后,后面查找的其实还是用的前面的S(57)或者S(56),自己把f[i]打个表就知道了

    学姐的代码:

    #include<stdio.h>
    #define ll long long
    #define MAXM 1000000000015L
     
    ll T;
    ll len[505];
    char* s1 = "COFFEE";
    char* s2 = "CHICKEN";
    ll noww[15][5];
     
    int main()
    {
        scanf("%lld", &T);
         
        len[1] = 6;
        len[2] = 7;
        for(ll i = 3; i <= 500; i ++){
            len[i] = len[i - 1] + len[i - 2];
            if(len[i] > MAXM) len[i] = MAXM;
        }
         
        while(T --){
            ll n, k;
            scanf("%lld%lld", &n, &k);
            for(int i = 0; i < 10; i ++){
                if(k + i <= len[n]){
                    noww[i][0] = n;
                    noww[i][1] = k + i;
                }
                else{
                    noww[i][0] = 0;
                    noww[i][1] = 0;
                }
            }
            for(int i = n; i >= 3; i --){
                for(int j = 0; j < 10; j ++){
                    if(noww[j][0] == i){
                        if(noww[j][1] <= len[i - 2])
                            noww[j][0] = i - 2;
                        else{
                            noww[j][0] = i - 1;
                            noww[j][1] = noww[j][1] - len[i - 2];
                        }
                    }
                }
            }
            for(int i = 0; i < 10; i ++){
                if(noww[i][0] == 1)
                    printf("%c", s1[noww[i][1] - 1]);
                else if(noww[i][0] == 2)
                    printf("%c", s2[noww[i][1] - 1]);
            }
            printf("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    关于数据源跟事件封装实例
    IOS开发基础知识--碎片27
    IOS开发基础知识--碎片26
    IOS开发基础知识--碎片25
    iOS菜单滚动联动内容区域功能实现
    IOS开发基础知识--碎片24
    iOS仿京东分类菜单之UICollectionView内容
    iOS仿京东分类菜单实例实现
    IOS开发基础知识--碎片23
    通用性好的win2003序列号: (推荐先用这个里面的)
  • 原文地址:https://www.cnblogs.com/wizarderror/p/11369218.html
Copyright © 2011-2022 走看看