階乗とは数学の演算の一つで、N の階乗をN! と書きます。N が自然数であるとき、階乗は次のように計算できます。
N! = N * (N - 1) * ... * 2 * 1
N が与えられたとき、N! のすべての桁の代わりに、N! の最下位桁から続く0 をすべて除いた値の下位9桁を求めるプログラムを作成してください。
9桁ではあるが先頭が0であるような場合は先頭の0を取り除いた値を出力してください。先頭に0のついた値を出力すると誤答となります。
例えば N = 38 の時は以下のようになります。
条件
すべてのテストケースにおいて、以下の条件をみたします。1 ≦ N ≦ 1000000
參考做法(只使用int處理)
#include <iostream>
using namespace st
int main(void){
// 自分の得意な言語で
// Let's チャレンジ!!
string str;
getline(cin, str);
int n = atoi( str.c_str() );
// 先計算 2與5的因數量
int c2 = 0;
int c5 = 0;
for (int i = 2; i <= n; i++)
{
int val = i;
while (((val % 2) == 0) && val > 1)
{
val /= 2;
c2++;
}
while ((val % 5 == 0) && val > 1)
{
val /= 5;
c5++;
}
}
c2 = c5 = c2 > c5 ? c5 : c2;
int ans = 1;
for (int i = n; i > 1; i--)
{
int val = i;
while (c2 > 0 && (val % 2 == 0) && val > 1)
{
val /= 2;
c2--;
}
while (c5 > 0 && (val % 5 == 0) && val > 1)
{
val /= 5;
c5--;
}
int a1 = (ans / 10000);
int a2 = (ans % 10000);
int b1 = (val / 10000);
int b2 = (val % 10000);
int ans1 = (((a1 * b1) % 10) ); // * 100000000
int ans2 = ((((a1 * b2) % 100000) * 10000) + (((a2 * b1) % 100000) * 10000) + (a2 * b2));
int ans3 = (ans2 / 100000000);
int ans4 = ans2 - (ans3 * 100000000);
int ans5 = ((ans1 + ans3) % 10) * 100000000;
ans = (ans4 + ans5) % 1000000000;
}
cout << ans << endl;
return 0;
}
參考做法2(使用long long處理)
unsigned long long getAxB(unsigned long long a, unsigned long long b)
{
unsigned long long ans = (a * b);
while ((ans % 10 == 0) && ans > 1) ans /= 10;
return ans % 10000000000; // 避免位數不足 這邊多個0
}
int main(void){
// 自分の得意な言語で
// Let's チャレンジ!!
string str;
getline(cin, str);
unsigned long long n = atoi( str.c_str() );
unsigned long long ans = n > 0 ? n : 1;
for (int i = n - 1; i > 1; i--) ans = getAxB(ans, i);
ans %= 1000000000;
cout << ans << endl;
return 0;
}
參考做法3(使用JS處理)
process.stdin.on('data', function (chunk) {
var line = chunk.toString();
var n = parseInt(line);
function getAxB(a, b)
{
var ans = a * b;
while (ans % 10 == 0 && ans > 1) ans /= 10;
return ans % 10000000000;
}
var ans = 1;
for (var i = n; i > 1; i--) ans = getAxB(ans, i);
console.log(ans % 1000000000);
});
感想
題目不難,但 debug環境不太友善,輸出結果不正確不會告訴原因.
因為只需要紀錄9位數,所以直覺感覺可以使用int完成答案,
不過實際上在處理時若只保留9位數,會因消去後位0而有不足位的可能.
ex. N=100327
如果中途計算只保留9位數,最後答案可能為 ans=850809344
但實際的正確答案應為 ans=450809344
所以在只使用int的狀況下,必須要做預處理,先將有可能造成後位0的情況事先排除.
網址
https://paiza.jp/poh/ando?read=true
沒有留言:
張貼留言