zoukankan      html  css  js  c++  java
  • 数字游戏

    问题描述

      栋栋正在和同学们玩一个数字游戏。

      游戏的规则是这样的:栋栋和同学们一共n个人围坐在一圈。栋栋首先说出数字1。接下来,坐在栋栋左手边的同学要说下一个数字2。再下面的一个同学要从上一个同学说的数字往下数两个数说出来,也就是说4。下一个同学要往下数三个数,说7。依次类推。

      为了使数字不至于太大,栋栋和同学们约定,当在心中数到 k-1 时,下一个数字从0开始数。例如,当k=13时,栋栋和同学们报出的前几个数依次为:
      1, 2, 4, 7, 11, 3, 9, 3, 11, 7。

      游戏进行了一会儿,栋栋想知道,到目前为止,他所有说出的数字的总和是多少。
    输入格式
      输入的第一行包含三个整数 n,k,T,其中 n 和 k 的意义如上面所述,T 表示到目前为止栋栋一共说出的数字个数。
    输出格式
      输出一行,包含一个整数,表示栋栋说出所有数的和。
    样例输入
    3 13 3
    样例输出
    17
    样例说明
      栋栋说出的数依次为1, 7, 9,和为17。
    数据规模和约定
      1 < n,k,T < 1,000,000;

    Algorithm

    最近感冒,大脑有点不好使,先是斐波那契函数,又来一个简单的数列都不会了。

    先写一篇博客安慰一下这几天没有发博客的自己!

    这种题型,都司空见惯了,看了下数据,一般模拟都会超时,再有,模拟大家都会,肯定不会让你模拟就过关。

    数列,那么就可以有A(n)和S(n)的通项公式,我们可以直接求出我们需要的那一项,唯一需要注意的就是一旦数据过大,就会爆掉,为此我还用了快速乘,发现,没什么用,后来发现是知识不到位......

    Mathtype敲公式很烦,博客园又不支持markdown,所以我就手打了。

    好,现在我们知道A(1) = 1

    - A(0) = 1;
    - A(n) = n + A(n-1)
    - A(n-1) = n-1 + A(n-2)
    - A(n-2) = n-2 + A(n-3)
    - ......
    - A(2) = 2 + A(1)
    - A(1) = 1 + A(0)
    - A(0) = 0 + 1

    很容易得到A(n) = A(0) + S(n)

    其中,S(n)为等差数列n的前n项和。

    关键在于,我们求A(2n)时,

    不用再次求S(n),而是直接加上 n*n

    这相当于之前的每一项都加上 n,这样数据就不会爆掉。

    A(2n) = A(n) + s(n) + n*n


    AC

     1 /*
     2 - A(0) = 1;
     3 - A(n) = n + A(n-1)
     4 - A(n-1) = n-1 + A(n-2)
     5 - A(n-2) = n-2 + A(n-3)
     6 - ......
     7 - A(2) = 2 + A(1)
     8 - A(1) = 1 + A(0)    
     9 - A(0) = 0 + 1
    10 */
    11 #include<iostream>
    12 #include<cstring>
    13 using namespace std;
    14 
    15 typedef long long ll;
    16 
    17 // 快乘 
    18 ll QMul(ll a, ll b)
    19 {
    20     if(a < b) {a ^= b;b ^= a;a ^= b;}
    21     ll s = 0;
    22     while(b)
    23     {
    24         if(b&1) s += a;
    25         a = (a<<1);
    26         b >>= 1;
    27     }
    28     return s;
    29 }
    30 
    31 int main()
    32 {
    33     ll n, k, T;
    34     n = k = T = 0;
    35     while(cin>>n>>k>>T)
    36     {
    37         ll s = 1, an = 1, c = n*(n+1)/2;T--;
    38         while(T--)
    39         {
    40             an = (an + c)%k;
    41             s += an;
    42             c += QMul(n, n);
    43         }
    44         cout<<s<<endl;
    45     }
    46     
    47     return 0;
    48 }
    View Code

    2019-01-22

    12:16:49

  • 相关阅读:
    稀疏数组和队列
    JVM中的GC算法,JVM参数,垃圾收集器分类
    Java虚拟机OOM问题和四大引用问题简述
    DLC双端锁,CAS,ABA问题
    CountDownLanuch,CyclicBarrier,Semaphore,Lock问题
    Callable,阻塞队列,线程池问题
    Android View的绘制机制前世今生---前世
    Android触摸事件传递机制,这一篇就够了
    flutter 与 android 混合开发
    Git 快速极简图文教程 第一篇
  • 原文地址:https://www.cnblogs.com/mabeyTang/p/10303123.html
Copyright © 2011-2022 走看看