zerojudge d122. Oh! My Zero!!
zerojudge d122. Oh! My Zero!!
千萬別用暴力解( 1a和2a的解法)!!,因為一定會TLE。
千萬別用2b!!,因為輸入很大(長整數),這樣字要用很大的記憶體,會出現錯誤(RE),我試過,真的。
解法大全:
1.依思路分:
a)直接算階乘
b)算5法
2.建表
a)建階乘表
b)建5表
千萬別用暴力解( 1a和2a的解法)!!,因為一定會TLE。
千萬別用2b!!,因為輸入很大(長整數),這樣字要用很大的記憶體,會出現錯誤(RE),我試過,真的。
思路:
數學歸納法
1.
首先,你要先了解10=2*5,且2出現的次數比5多
所以要算出現比較少的次數(5的次數)
2.
再來你得先寫兩個表格
分別為,
a)5的倍數數字的質因數中有多少的5(5的倍數數字可以整除幾次5)
用數學式表示:n=k*5^m (k,m為正整數)
b)輸入和輸出的關係
3.
找規律
我的解法:
先用這方式寫
2b)先建表(1~1000000中能被5整除的次數),在逐項加起來
#define PO 7
const int MX=pow(10.0,PO);//because n is too large
// MX=pow(10.0,5);
typedef long long int LLI;
int five_n[MX]={0};
void print(int *,int );
void build()
{
//memset(five_n,0,sizeof(five_n));
for(int i=1;i<=PO;i++)
{
int n=pow(5.0,i);
for(int j=n;j<=MX;j+=n)
{
five_n[j]++;
}
}
return ;
}
int deal(LLI n)
{
int sum=0;
for(int i=5;i<=n;i+=5)
{
sum+=five_n[i];
}
return sum;
}| RE (SIGSEGV) |
1b)算5法:就是輸入一個數字N,算N!可以被5除多少次
因為末位數是0或5的才能被5整除
因為N!=1*2*3*4*5*...*N
只要算1~N中末位數是0或5的數字可以被5整除的次數,加起來就是答案
但是我發現一個規律,5可以被5整除1次,10是1次,25是兩次
在1~N中有N/5個是5的倍數,有N/25個是25個倍數
ans=in/5+in/25+in/125+...
所以我可以化簡成:
int ans=0;
LLI n=1;
for(int i=1;n<=in;i++)
{
n=pow(5.0,i);
ans+=in/n;
}
cout<<ans<<endl;//or
int ans=0;
LLI n=1;
for(int i=1;n<=in;i++)
{
n*=5;
ans+=in/n;
}
cout<<ans<<endl;| //AC (2ms, 312KB) |
註:
因為這題比較難,所以有不懂的可以在下面留言
還有我沒寫所有的方法,若有新解法(請先測試),可以在下面留言
也要謝謝別人的解題報告,它提供我一些想法
Comments
Post a Comment