Factovisors - PC110704

歡迎訪問我的新博客:http://www.milkcu.com/blog/

原文地址:http://www.milkcu.com/blog/archives/uva10139.html

原創:

作者:MilkCu

題目描述

Problem D: Factovisors

The factorial function, n! is defined thus for n a non-negative integer:
   0! = 1
   n! = n * (n-1)!   (n > 0)
We say that a divides b if there exists an integer k such that
   k*a = b
The input to your program consists of several lines, each containing two non-negative integers, n and m, both less than 2^31. For each input line, output a line stating whether or not m divides n!, in the format shown below.

Sample Input

6 9
6 27
20 10000
20 100000
1000 1009

Output for Sample Input

9 divides 6!
27 does not divide 6!
10000 divides 20!
100000 does not divide 20!
1009 does not divide 1000!

解題思路

思路比較流暢,依次求2~n之間的數與m的最大公約數,然後用公約數去除m。
若m能被除盡,則m可以整除n!;否則不能。
但是提交到UVaOJ爲什麼會超時呢?看來還需要優化。

如果在遍歷2~n之間的數時,遇到的數i爲質數。
若m爲素數且m>n,則m與2~n中的任何數互素。
其他優化:把開方放在循環外邊。
從n到2遞減尋找最大公約數可以提高效率。

還要注意特殊情況的處理。

PC可以通過,UVaOJ總是超時,太浪費時間了。
對於我的不高的要求,以後使用PC吧。

兩種求最大公約數的方法:

1. 遞歸

int gcd(int a, int b) {
	if(b == 0) {
		return a;
	}
	if(a < b) {
		return gcd(b, a);
	}
	return gcd(b, a % b);
}
2. 循環

int gcd(int a, int b) {
	if(a < b) {
		int tmp = a;
		a = b;
		b = tmp;
	}
	while(b > 0) {
		int tmp = a;
		a = b;
		b = tmp % b;
	}
	return a;
}

代碼實現

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int isPrime(int x) {
	int sq = sqrt(x);
	for(int i = 2; i <= sq; i++) {
		if(x % i == 0) {
			return 0;
		}
	}
	return 1;
}
int gcd(int a, int b) {
	if(a < b) {
		int tmp = a;
		a = b;
		b = tmp;
	}
	while(b > 0) {
		int tmp = a;
		a = b;
		b = tmp % b;
	}
	return a;
}
int main(void) {
	int n, m;
	while(cin >> n >> m) {
		if(m == 0) {
			cout << m << " does not divide " << n << "!" << endl;
			continue;
		}
		if(m == 1) {
			cout << m << " divides " << n << "!" << endl;
			continue;
		}
		if(isPrime(m) && m > n) {
			cout << m << " does not divide " << n << "!" << endl;
			continue;
		}
		int tm = m;
		for(int i = n; i >= 2; i--) {
			int g = gcd(i, tm);
			if(g > 1) {
				//cout << i << "  " << g << endl;
				tm /= g;
			}
			if(tm == 1) {
				cout << m << " divides " << n << "!" << endl;
				break;
			}
		}
		if(tm != 1) {
			cout << m << " does not divide " << n << "!" << endl;
		}
	}
	return 0;
}

(全文完)

本文地址:http://blog.csdn.net/milkcu/article/details/23592449

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章