zoukankan      html  css  js  c++  java
  • hdu 5459 Jesus Is Here

    一道递推题

    感觉这种题找规律对我来说好困难……还是慢慢想吧

    题意:s1 = c,s2 = ff,s3 = cff,……s[i] = s[i - 2] + s[i - 1]

       从s5开始(s5 = cffffcff),出现了两个cff, 相隔为5,那么输出5

       s6 = ffcffcffffcff,输出所有cff之间距离的和,为3+5+8 = 16

       s[i],i<=201314,输出ans[i]

    思路:由题意发现了一些类斐波那契数列,字符串s[i] = s[i - 2] + s[i - 1],字符串长度len[i] = len[i - 1] + len[i - 2], 字符串中c的个数num[i] = num[i - 1] + num[i - 2]。

       然后需要记录字符串中c的位置和,以第一个字符的位置为1,那么sum[i] = sum[i - 1] + sum[i - 2] + len[i - 2] * num[n - 1]。

       关于ans,可以这样考虑, ans[i] = ans[i - 1] + ans[i - 2] + ?

       ?为i - 1和i - 2中cff之间的距离之和,首先算i - 1中所有c到i - 2的字符串串首的距离,既num[i - 1] * len[i - 2] + sum[i - 1]…………一式

       由于i - 2中有num[i - 2]个c,则一式需要乘上num[i - 2],既num[i - 1] * len[i - 2] * num[i - 2] + num[i - 2] * sum[i - 1] …………二式

       实际上i - 1中的c只需要移到i - 2中c的位置,于是二式需要减去sum[n - 2] * num[n - 1]

       化简可得ans[i] = ans[i - 1] + ans[i - 2] + (len[i - 2] * num[i - 2] - sum[i - 2]) * num[i - 1] + sum[i - 1] * num[i - 2]

       然后注意这四个数组都要开long long,不然会溢出,取模要对每一个都取。

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 
     4 using namespace std;
     5 
     6 const int N = 201314 + 1;
     7 const int mod = 530600414;
     8 typedef long long ll;
     9 
    10 ll len[N], num[N], sum[N], ans[N];
    11 
    12 int main()
    13 {
    14     int t, n;
    15 
    16     cin>>t;
    17     len[0] = 1, len[1] = 2, len[2] = 3, len[3] = 5, len[4] = 8, len[5] = 13;
    18     num[0] = 1, num[1] = 0, num[2] = 1, num[3] = 1, num[4] = 2, num[5] = 3;
    19     sum[0] = 1, sum[1] = 0, sum[2] = 1, sum[3] = 3, sum[4] = 7, sum[5] = 20;
    20     ans[4] = 5, ans[5] = 16;
    21     for(int i = 5; i < N - 1; i ++ ){
    22         len[i+1] = (len[i] + len[i-1]) % mod;
    23         num[i+1] = (num[i] + num[i-1]) % mod;
    24         sum[i+1] = (sum[i] + sum[i-1] + len[i-1] * num[i]) % mod;
    25         ans[i+1] = (ans[i] + ans[i-1] + (((len[i-1] * num[i-1] - sum[i-1]) % mod) * num[i]) % mod + (sum[i] * num[i-1]) % mod) % mod;
    26 
    27     }
    28     int flag = 0;
    29     while(t -- ){
    30         flag ++ ;
    31         scanf("%d", &n);
    32         printf("Case #%d: ", flag);
    33         printf("%d
    ", ans[n-1]);
    34     }
    35     return 0;
    36 }
    View Code

    写题解整理了一遍思路(

    感觉清楚多了

  • 相关阅读:
    第七次作业
    rfid工作原理
    实验九——基本数据类型存储及应用总结
    实验八——函数定义及调用总结
    实验七——函数定义及调用总结
    作业
    作业
    作业
    开始
    实验12——指针的基础应用2
  • 原文地址:https://www.cnblogs.com/moomight/p/11426463.html
Copyright © 2011-2022 走看看