• POJ 4010 2011


    http://poj.grids.cn/practice/4010/

    /**********************************************************************************
    4010 - 2011

    时间限制:
        1000ms
    内存限制:
        65536kB

    描述
        已知长度最大为200位的正整数n,请求出2011^n的后四位。
    输入
        第一行为一个正整数k,代表有k组数据,k<=200接下来的k行,

        每行都有一个正整数n,n的位数<=200
    输出
        每一个n的结果为一个整数占一行,若不足4位,去除高位多余的0
    样例输入

        3
        5
        28
        792

    样例输出

        1051
        81
        5521
    *********************************************************************************
    */

    /**********************************************************************************
    解题思路:

        abcd
        abcd
        .......
        abcd
        abcd
        abcd
      *abcd
    -----------
    ....ABCD

    假设一个数(abcd)^n的结果的后四位是:ABCD,那么可以得到:
    D = ( d^n )%10                                      进位t1 = (d^n) / 10
    C = ( n*c*(d^(n-1)) + t1 ) % 10                进位t2 =  ( n*c*d^(n-1) + t1 ) / 10
    B = ( n*b*(d^(n-1)) + (n*(n-1)/2)*(c^2)*(d^(n-1)) + t2 ) % 10         进位t3
    A = ( n*a*(d^(n-1)) + (n*(n-1)/2)*b*c*(d^(n-2)) + (n*(n-1)*(n-2)/6)*(c^3)*(d^(n-3)) + t3 )%10

    其中:(n*(n-1)/2)表示组合数Cn2, (n*(n-1)*(n-2)/6)表示组合数Cn3。
    由于a = 2, b = 0, c = 1, d = 1已知,那么带入可得:
    D = 1,  t1 = 0
    C = n%10, t2= n / 10
    B = ( n*(n-1)/2 + t2 ) % 10, t3 =  ( n*(n-1)/2 + t2 ) / 10
    A = ( 2*n +  n*(n-1)*(n-2)/6 + t3) % 10

    带入样例输入可知正确性。

    最后的难度在于n太大了,有200位,我们可以考虑是不是存在一个数t,使得:
    (2011)^t 的末四位仍然是2011??
    那么就是解方程令D = 1, C = 1, B = 0, A = 2求出t>1的最小正整数,我们尝试t = 1001,满足要求。
    再尝试t = 101不满足。再尝试501满足。所以就可以对所有的n,我们取末三位再模除500。
    注意,t = 500时候,(2011)^t的末四位就是0001。所以(2011)^(t+1)的末四位就是2011.
    *********************************************************************************
    */

    #include 
    <iostream>
    #include 
    <cmath>
    #include 
    <cctype>
    #include 
    <string>
    #include 
    <map>
    #include 
    <set>
    #include 
    <vector>
    #include 
    <algorithm>
    #include 
    <list>
    //#include <stdlib.h>
    //#include <iomanip>

    using namespace std;

    int main()
    {
        
    int k, n, len, ans;
        
    int a[4], t2, t3;
        
    string str;
        cin 
    >> k;
        
    for (int i = 0; i < k; i++)
        {
            cin 
    >> str;
            len 
    = str.length();
            n 
    = 0;
            
    for (int j = len-1, t = 1; j >= 0 && j >= len - 3; j--)
            {
                n 
    += (str[j] - '0'* t;
                t 
    *= 10;
            }
            n 
    %= 500;

            a[
    0= 1;
            a[
    1= n%10;
            t2
    = n/10;
            a[
    2= n*(n-1)/2 + t2;
            t3 
    = a[2]/10;
            a[
    2%= 10;
            a[
    3= ( 2*+  n*(n-1)*(n-2)/6 + t3) % 10;

            ans 
    = a[0+ a[1]*10 + a[2]*100 + a[3]*1000;

            cout 
    << ans << endl;
        }

        
    return 0;
    }


  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 校门外的树
    Java实现 蓝桥杯VIP 算法训练 统计单词个数
    Java实现 蓝桥杯VIP 算法训练 统计单词个数
    Java实现 蓝桥杯VIP 算法训练 开心的金明
    Java实现 蓝桥杯VIP 算法训练 开心的金明
    Java实现 蓝桥杯 算法训练 纪念品分组
    Java实现 蓝桥杯 算法训练 纪念品分组
    Java实现 蓝桥杯VIP 算法训练 校门外的树
    Java实现 蓝桥杯VIP 算法训练 统计单词个数
    Java实现 蓝桥杯VIP 算法训练 开心的金明
  • 原文地址:https://www.cnblogs.com/CCBB/p/1876042.html
Copyright © 2020-2023  润新知