Factorial

Factorial
     
 
時間限制:1秒    內存限制:256兆
題目描述

     Many years later, Alice grow up and she become a high-school student.One day she learned factorial on math class. The factorial of an integer N, written N!, is the product of all the integers from 1 through N inclusive.For example, 4! = 1 * 2 * 3 * 4 = 24, Likewise, 5! = 1 * 2 * 3 * 4 * 5 = 120.

    Alice found that the factorial quickly becomes very large, and she want to find the rightmost non-zero digit of N!.
輸入格式

 There are T(1 <= T <= 50) test cases. For each test case, A single positive integer N no larger than 10000 and no smaller than 1. 

輸出格式

 Each test case a single line containing a single digit: the right most non-zero digit of N!.

樣例輸入
4
4
5
6
7
樣例輸出
4
2
2
4

這題如果單純的用遞歸或直接階乘遇到比較大的數據時,肯定超時,可以先把前10個數據枚舉出來,比10大的再討論。尾數爲零不外乎都是尾數爲偶數和尾數爲5的數相乘得到的,定義F(n)爲所要求的數,G(n)爲1,2…n中將5的倍數的數換成1後的各項乘積(如:G(15)=1*2*3*4*1*6*7*8*9*1*11*12*13*14*1)(G(n)%10必不爲0)。只要把符合這個規律的數對破壞即可。不妨令其中尾數爲5的數先看作1,定義F(n)爲所要求的數,G(n)爲1,2…n中將5的倍數的數換成1後的各項乘積(如:G(15)=1*2*3*4*1*6*7*8*9*1*11*12*13*14*1)(G(n)%10必不爲0)。則n!=(n/5)!*5^(n/5)*G(n),F(n)=F(n/5)*[5^(n/5)*G(n)%10],這可用遞歸處理,另外觀察到5^(n/5)*G(n)%10=G(n)/2^(n/5)%10,這裏G(n)%10(n>=10)其實是個週期爲10的週期序列(程序中的table),G(n)/2^(n/5)必爲偶數,這樣得到一種特殊除法:8/2=4,4/2=2,2/2=6,6/2=8…,這樣G(n)/[2^(n/5)]%10只與G(n)%10和(n/5)%4有關。而G(n)%10=table[n%10],n/5%4=n/5%100%4(%100好算,就是最後兩位數字)。


#include
#include
using namespace std;
char n[1000];
int  b[1000];
const int m[10]={1,1,2,6,4,2,2,4,2,8};
const int table[10]={6,6,2,6,4,4,4,8,4,6};
const int even[4]={8,4,2,6};
int div2(int a, int c)
{
    int i;
    for(i=0; i<4 && even[i]!=a; i++);
    if(i>=4)
        return 0;
    return even[(i+c)%4];
}
int lastbit(char*s)
{
    int len=strlen(s);
    if(len<2)
        return m[s[0]-'0'];
    int i, c, bit=1;
    for(i=len-1; i>=0; i--)
        b[len-1-i]=s[i]-'0';
    while(len>1)
    {
        int k = b[0];
        for(i=1,c=b[0]/5; i<=len; i++)
        {
            c = b[i] * 2 + c;
            b[i-1] = c % 10;
            c /= 10;
        }
        len -= !b[len-1];
        bit = bit * div2(table[k],b[0]+b[1]*10) % 10;
    }
    bit = bit * m[b[0]] % 10;
    return bit;
}
int main()
{
	int num;
	cin>>num; 
    while(num--)
    {
    	cin>>n;
    	cout<
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章