• P1134 阶乘问题


    题目描述

    也许你早就知道阶乘的含义,N阶乘是由1到N相乘而产生,如:

    12! = 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x 11 x 12 = 479,001,600

    12的阶乘最右边的非零位为6。

    写一个程序,计算N(1<=N<=50,000,000)阶乘的最右边的非零位的值。

    注意:10,000,000!有2499999个零。

    输入输出格式

    输入格式:

    仅一行包含一个正整数N。

    输出格式:

    单独一行包含一个整数表示最右边的非零位的值。

    输入输出样例

    输入样例#1: 复制
    12
    输出样例#1: 复制
    6

    数论题 

    错误的想法:

    把5全部放一起乘就剩下一个5, 10的话全部忽略,剩下12346789相乘为6,每十个一组6*偶数都不变。。。

    更正思路:

    5放一起乘取尾数5是绝对错误的做法,因为偶数与5相乘是看倒数第二位的(是变化的),比如15,25,35,45分别乘6尾数去零后结果都不一样的!!!

    正解:

    1.若输入大于1,则结果必为2,4,6,8其中之一

    因为因子2的个数大于5,用2与5进行抵消的话,最终始终还剩下2!!

    2.可以将所有乘5替换成乘8(省去了消零的工作)

    当x为4的倍数,那么x乘5和乘8效果是一样的

    且阶乘中4的倍数不少于5的倍数

    3.若x为偶数,x乘6结果仍是x

    这一点可以用在周期上(12346789相乘为6)

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 100000
    typedef long long ll;
    #define inf 2147483647
    #define ri register int
    
    int n;
    int ans = 1;
    int a[4] = {6, 8, 4, 2}; //8^4 8^1 8^2 8^3 的尾数
    int main() {
      // ios::sync_with_stdio(false);
      // freopen("test.txt", "r", stdin);
      //  freopen("outout.txt","w",stdout);
      cin >> n;
    if(n==1){
    cout<<1;
    return 0;
    }
      while (n) {
        for (int i = 1; i <= n % 10; i++)
          if (i != 5)//暴力乘出(n%10(去掉5))
            ans = (ans * i) % 10;
        n /= 5;//n/5即少乘了多少次5
        ans = (ans * a[n % 4]) % 10;//四次一循环,算8^(k%4)
    //while循环,用同样的方法再算5 10 15 20 ...除以5后形成的1 2 3 4 ...!
      }
      cout << ans;
    
      return 0;
    }
  • 相关阅读:
    Oracle问题之ORA-12560TNS:协议适配器错误
    调用脚本的方式自动的创建或者是更新oracle数据库自带的Seq序列号的值
    linux在telnet情况下root登录提示login incorrect
    CentOS 7 中 Systemd详解
    CentOS7 下安装telnet服务
    linux 安装telnet命令及使用
    Linux安装telnet
    Linux系统xinetd服务启动不了
    linux服务安装与配置(二):安装xinetd服务
    Linux超级守护进程——xinetd
  • 原文地址:https://www.cnblogs.com/planche/p/8523097.html
Copyright © 2020-2023  润新知