• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

陈体胖

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

算法笔记 P167 例题:【PAT A1059】Prime Factors

算法笔记练习 题解合集

题目链接

题目

Given any positive integer N, you are supposed to find all of its prime factors, and write them in the format N=p1k1×p2k2x⋯×pmkmN=p_1^{k_1}\times p_2^{k_2}x\dots\times p_m^{k_m}N=p1k1​​×p2k2​​x⋯×pmkm​​.

Input Specification:

Each input file contains one test case which gives a positive integer NNN in the range of long int.

Output Specification:

Factor NNN in the format NNN=p1p_1p1​^k1k_1k1​*p2p_2p2​^k2k_2k2​*…\dots…*pmp_mpm​^kmk_mkm​​​ , where pip_ipi​'s are prime factors of N in increasing order, and the exponent kik_iki​​​ is the number of pip_ipi​ – hence when there is only one pip_ipi​​​, kik_iki​​​ is 1 and must NOT be printed out.

Sample Input:
97532468
Sample Output:
97532468=2^2*11*17*101*1291

思路

步骤 3 和步骤 4 被整合成了质因子分解函数primeFactorization,具体实现看代码。

  1. 开素数表,判断到略大于 231\sqrt{2^{31}}231​ 即可;
  2. 由于 2×3×5×7×11×13×17×19×23>231−12\times3\times5\times7\times11\times13\times17\times19\times23>2^{31}-12×3×5×7×11×13×17×19×23>231−1,所以统计因式分解结果的数组开到 10 就够了,开数组factors[10],初始化;
  3. 遍历素数表primeTable,对num进行因式分解,令n = num:
    a. 当primeTable[i] > sqrt(num)时停止遍历;
    b. 若primeTable[i]能整除n,把该素数的值写入factors[i].x;
    c. 不断用primeTable[i]去除n,直至不能整除,同时统计除的次数,写入factors[i].exp;
  4. 遍历结束后,若n == 1,说明因式分解完毕,否则,还剩下一个大于sqrt(num)的大因子,将其信息写入factors;
  5. 根据factors输出答案。

细节:

  • factors为什么要开10而不是9?因为要给步骤 4 的大因子留一个位置;
  • 需要特判输入为1的情况;
  • 在正式进行因式分解的部分,不能直接对num动手,要留副本;
  • 大数组要开成全局变量,不能开在main或者其他函数里面,否则会造成段错误。

代码

#include <stdio.h>
#include <math.h> 

#define MAX 50000

typedef struct {
	int x, exp;
} Factor; 

// 打素数表 
int isPrime[MAX], primeCnt = 0, primeTable[MAX/10];
int findPrime(void) {
	int i, j;
	for (i = 2; i < MAX; ++i)
		isPrime[i] = 1;
	for (i = 2; i < MAX; ++i) {
		if (isPrime[i]) {
			primeTable[primeCnt++] = i; 
			for (j = i; j < MAX; j += i)
				isPrime[j] = 0; 
		} 
	} 
} 

// 对 num 质因子分解,结果放入 factors,返回质因子数量 
// 要求 num >= 2 
int primeFactorization(int num, Factor *factors) {
	int i, n = num;		// n 是 num 的副本 
	int factorCnt = 0;
	for (i = 0; i < 10; ++i)
		factors[i].exp = 0;
	for (i = 0; i < primeCnt; ++i) {
		if ((int)sqrt((double)num) < primeTable[i])
			break;
		if (n % primeTable[i] == 0) {
			factors[factorCnt].x = primeTable[i];
			while (n % primeTable[i] == 0) {
				n /= primeTable[i];
				++factors[factorCnt].exp;
			}
			++factorCnt;
		}
	}
	if (n != 1) {
		factors[factorCnt].x = n;
		factors[factorCnt].exp = 1;
		++factorCnt;
	}
	return factorCnt;
} 

int main() {
	findPrime();		// 打表 
	int num, i;
	scanf("%d", &num);
	if (num == 1) {		// 特判 
		printf("1=1");
		return 0;
	}
	// 质因子分解 
	Factor factors[10];
	int factorCnt = primeFactorization(num, factors);
	// 输出 
	int flag = 0;
	printf("%d=", num); 
	for (i = 0; i < factorCnt; ++i) {
		if (flag)
			putchar('*');
		flag = 1;
		printf("%d", factors[i].x);
		if (factors[i].exp > 1) 
			printf("^%d", factors[i].exp); 
	} 
	return 0;
} 

posted on 2020-03-31 15:28  陈体胖  阅读(158)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3