• 1066 Last non-zero Digit in N!


    题目做不出 看答案:参考文献
     https://www.xuebuyuan.com/1394116.html
    https://blog.csdn.net/orangesix/article/details/44190501(在下面的8/2还是什么 只要因子2的数量还有 都不会尾数绝对不会是奇数)
    http://blog.sina.com.cn/s/blog_59e67e2c0100a7yx.html(里面讲了两种解法 第一种也是对一下第一种代码进行修改 ~但超时了)
    https://blog.csdn.net/a601025382s/article/details/38174939
    一开始想的是一直保留最后一位 只要是0 就把他去掉 这个代码一开始答案正确就没有去多想 然后提交失败后想了很久,发现我们只关心最后一位 却忘了前一位也是跟前一位的值有关系的 这样就导致了误解 一些需要两位数起作用 我们一直保留最后一位这个方法是错误的,一个数相乘答案跟其他位置都有密切联系。
    例如 我们把98*5 答案是490 尾数正确是9 ,但是我们取尾数相乘的话 仅仅才4 这就是问题所在。

    import java.util.Scanner;
     
    public class Main {
     
    	public static void main(String[] args) {
    		Scanner sc = new Scanner(System.in);
    		while (sc.hasNext()) {
    			long n = sc.nextLong();
    			long count = 1;
    			for (int i = 1; i <= n; i++) {
    				count *= i;
    				while (count % 10 == 0) 
    					count /= 10;
    					count %= 10;
    			}
    				System.out.println(count);
    		}
    	}
    }
    

    所以要改用其他方法
    https://baike.baidu.com/item/阶乘/4437932?fromtitle=n!&fromid=7806135
    看了一整天 还是看不懂 突然睡着睡着想到了

    //
    //  main.c
    //  HDOJ1066
    //
    //  Created by Egger on 18/1/15.
    //  Copyright (c) 2015年 Egger. All rights reserved.
    //
     
    #include <stdio.h>
    #include <string.h>
    #define SIZE 10
    #define MAXH 1000
     
    char Str[MAXH];
    int Num[MAXH];
     
    const int FirstTen[SIZE] = {1,1,2,6,4,2,2,4,2,8};
    const int Table[SIZE] = {6,6,2,6,4,4,4,8,4,6};
    const int DivisionCircle[4] = {2,6,8,4};
     
     
    int H(int X, int Y)//y小于100  跟百位没有多大关系
    {
     
        int i;
     
        for(i = 0; i < 4; i++)
        {
            if (X == DivisionCircle[i])
            {
                break;
            }
        }
     
        return DivisionCircle[(i+Y)%4];
    }
     
    int F(char* s)
    {
        int i,k;
        int Bit,Carry,Len,Result;
        
        Len = (int)strlen(s);
        Result = 1;
        
        if(Len < 2)
        {
            return FirstTen[s[0]-'0'];
        }
        
        for(i = Len - 1; i >= 0; i--)
        {
            Num[Len-1-i] = s[i] - '0';
        }
        while(Len > 1)
        {
            k = Num[0];
            Carry = 0;
            Num[Len] = 0;
            for(i = 0; i <= Len; i++)
            {
                Bit = Num[i] * 2 +Carry;//因为要把它传到(n/5!相当于*2/10)
                Num[i] = Bit % 10;//适用于所有的数 别管被截掉的尾位
                Carry = Bit / 10;
            }
            for(i = 1; i <= Len; i++)
            {
                Num[i-1] = Num[i];
            }
            if(Num[Len] == 0)
                Len --;
            
            Result = Result * H(Table[k], Num[0]+Num[1]*10) % 10;//因为每四位一个循环 所以跟百位以上没多大联系
        }
        
        Result = Result * FirstTen[Num[0]] % 10;
        
        return Result;
    }
     
    int main(int argc, const char* argv[])
    {
     
        while(scanf("%s",Str) != EOF)
        {
            printf("%d
    ",F(Str));
        }
        return 0;
    }
    

    ~~整理很久的思路 终于想清楚了 ~ 改写成java 有不懂可以留言

    import java.util.*;
     
    public class Main {
    	static int num = 1000;//因为输入值位1000位的数 所以采用数组一个位一个位保存
    	static int FirstTen[] = { 1, 1, 2, 6, 4, 2, 2, 4, 2, 8 };//结合上面的代码 一个一个写
    	static int DivisionCircle[] = { 2, 6, 8, 4 };
    	static int Table[] = { 6, 6, 2, 6, 4, 4, 4, 8, 4, 6 };
     
    	public static int H(int X, int Y) {
    		int i;
    		for (i = 0; i < 4; i++) {
    			if (X == DivisionCircle[i]) {
    				break;
    			}
    		}
    		return DivisionCircle[(i + Y) % 4];//因为除数是循环 先找出i的位置 在向右移动Y位,每四位循环一次 所以%4
    	}
     
    	public static int funcation(int arr[], int len) {
    		int res = 1;
    		int k;
    		int carry;
    		int bit;
    		while (len > 1) {
    			k = arr[0];
    			carry = 0;
    			arr[len] = 0;
    			for (int i = 0; i <= len; i++) {
    				bit = arr[i]*2 + carry;
    				carry = bit / 10;
    				arr[i] = bit % 10;
    			}
    			for (int i = 1; i <= len; i++) {
    				arr[i - 1] = arr[i]; //可能有些人会想 arr[i-1]不为零 移位覆盖了 不影响吗 真的不影响 因为我们只要求  n/5  按照另外一篇推文里面介绍的递推公式(符合) 包括16/5 = 3 我们只要知道要除有几个2就好
    			}
    			if (arr[len] == 0) {//持续记录剩下的数的长度
    				len--;
    			}
    			res = res * H(Table[k],arr[0]+arr[1]*10)%10;//结合另外一篇递推公式
    		}
    		return res * FirstTen[arr[0]] % 10;
    	}
     
    	public static void main(String[] args) {
    		Scanner sc = new Scanner(System.in);
    		while (sc.hasNext()) {
    			String n = sc.next();
    			if (n.length() < 2)
    				System.out.println(FirstTen[n.charAt(0) - '0']);
    			else {
    				int arr[] = new int[n.length() + 1];
    				for (int i = 0; i < n.length(); i++) {
    					arr[i] = n.charAt(n.length() - 1 - i) - '0';//逆序方便处理
    				}
    				System.out.println(funcation(arr, n.length()));
    			}
    		}
    	}
    }
    
  • 相关阅读:
    Scrum Meeting Beta
    Scrum Meeting Beta
    Scrum Meeting Beta
    Scrum Meeting Beta
    《人月神话》读后感
    【最后的总结】我们的Sprint3冲刺——闹钟的添加和管理(刘铸辉,何晓楠)
    【软件结课】软件工程课的评价
    【软件结课】软件工程课的收获
    springt2第二次冲刺计划表
    给出一个 m*n 的二维数组(元素可为正可为负),求该二维数组的一个子数组,且此子数组中所有元素的和最大,并输出该数组的和。
  • 原文地址:https://www.cnblogs.com/cznczai/p/11150220.html
Copyright © 2020-2023  润新知