Each input file contains one test case which gives a positive integer N in the range of long int.
Factor N in the format N = p1^k1 * p2^k2 *...*pm^km, where pi's are prime factors of N in increasing order, and the exponent ki is the number of pi -- hence when there is only one pi, ki is 1 and must NOT be printed out.
97532468
97532468=2^2*11*17*101*1291
#include <iostream> #include <cmath> using namespace std; struct fac{ //x为质因子,cnt为其个数 int x,cnt; }fac[20]; bool isprime(int n){ //判断是否为素数 if(n<=1) return false; if(n==2) return true; for(int i=2;i*i<=n;i++){ if(n%i==0) return false; } return true; } int main(){ int n,temp,num=0; //num为n的不同质因子个数 cin>>n; temp=n; if(n==1) cout<<"1=1"; //特例 else{ int sqr=(int)sqrt(1.0*n); for(int i=2;i<=sqr;i++){ if(isprime(i)){ //若为素数 if(n%i==0){ //且为n的因子 fac[num].x=i; //先记录该因子并初始化个数 fac[num].cnt=0; while(n%i==0){ //计算该质因子个数 fac[num].cnt++; n/=i; } num++; //不同质因子个数加1 } } if(n==1) break; //及时推出循环 } if(n!=1){ //无法被根号n以内的质因子除尽 fac[num].x=n; //必有一个大于根号n(即n本身)的质因子 fac[num++].cnt=1; } cout<<temp<<"="; for(int i=0;i<num;i++){ cout<<fac[i].x; if(fac[i].cnt!=1) cout<<"^"<<fac[i].cnt; if(i<num-1)cout<<"*"; } return 0; }
#include<stdio.h> int main() { long long n; while( scanf("%lld",&n)!= EOF ) { printf("%lld=",n); if( n == 1 ) printf("1"); int count = 0; //如果i是非素数则一定不会被整除,count记录幂次数 for( long long i = 2 ; i * i <= n ; i++ ) { while( n % i == 0 ) { count++; n = n / i; } if( count == 1 ) printf("%lld",i); else if( count == 0 ) continue; else printf("%lld^%d",i,count); count = 0; if( n != 1 ) printf("*"); } //循环最后的情况要么n = 1,说明最大的素因子幂次超过1 //要么 n 为一个素数,该素数也是最大的素因子且幂次数为1 if( n != 1 ) printf("%lld",n); printf("\n"); } return 0; }
//prime factors #include<iostream> #include<vector> #include<cmath> using namespace std; vector<int> prime; int amount[100000000]={0}; bool is_prime(int n){ bool flag=1; int n2=sqrt(n)+1; for(int i=2;i<n2;i++){ if(n%i==0)flag=0; } return flag; } void get_prime_factor(int n){ int cnt=2; while(n!=1&&cnt<=n){ if(is_prime(n)){ prime.push_back(n); amount[n]++; return; } if(is_prime(cnt)&&n%cnt==0){ prime.push_back(cnt); amount[cnt]++; n/=cnt; while(n%cnt==0){ amount[cnt]++; n/=cnt; } cnt=2; } else cnt++; } } int main(){ int n; cin>>n; if(is_prime(n)){ cout<<n<<"="<<n; return 0; } get_prime_factor(n); cout<<n<<"="<<prime[0]; if(amount[prime[0]]>1)cout<<"^"<<amount[prime[0]]; for(int i=1;i<prime.size();i++){ cout<<"*"<<prime[i];if(amount[prime[i]]>1)cout<<"^"<<amount[prime[i]]; } return 0; }
//数学知识背景:可能有大于sqrt(N)的质因数(指数必为1) #include <iostream> #include <math.h> #include <map> using namespace std; #define MAX 1500000 long int N; int p[MAX], k[MAX]; int cnt = 1; map<int, int> fac2index; bool isPrime(int x) { if (x == 2)return true; if (x % 2 == 0)return false; for (int i = 3; i <= sqrt(x); i += 2) { if (x % i == 0)return false; } return true; } void updateFac(int x) { if (!fac2index[x]) { p[cnt] = x; k[cnt] = 1; fac2index[x] = cnt++; } else ++k[fac2index[x]]; } int main() { cin >> N; int rem = N; for (int i = 2; i <= sqrt(rem);) { if (rem % i == 0 && isPrime(i)) { updateFac(i); rem /= i; } else ++i; } if (rem != 1) updateFac(rem); //数学知识背景:可能有大于sqrt(N)的质因数(此时其指数必为1) cout << N << "="; if (N == 1)cout << 1; else if (cnt == 1)cout << N; else for (int i = 1; i < cnt; ++i) { cout << p[i]; if (k[i] > 1)cout << "^" << k[i]; if (i < cnt - 1)cout << "*"; } return 0; }
#include<iostream> using namespace std; struct factor{ int x,cnt; }fac[10]; bool isprime(int n){ for(int i=2;i*i<n;i++) if(n%i == 0) return false; return true; } int main(){ long long int n; cin >> n; cout << n << "="; int num = 0; if(n==1) cout << n; else{ for(int i=2;i*i<n;i++){ if(isprime(i) && n % i == 0){ fac[num].x = i; fac[num].cnt = 0; while(n % i == 0){ fac[num].cnt++; n /= i; } num++; } } if(n!=1) { fac[num].x = n; fac[num++].cnt = 1; } for(int i=0;i<num;i++){ cout << fac[i].x; if(fac[i].cnt!=1) cout << "^" << fac[i].cnt; if(i!=num-1) cout << "*"; } } return 0; }
#include <bits/stdc++.h> using namespace std; map<int, int> prime_cnt; void solution(int n) { for (int i = 2; i <= sqrt(n); i++) { int cnt = 0; while (n % i == 0) { cnt++; n /= i; } if(cnt != 0) prime_cnt[i] = cnt; } if (n != 1) prime_cnt[n] = 1; } int main() { int N; cin >> N; if (N == 1) prime_cnt[1] = 1; else solution(N); cout << N << "="; for (auto p : prime_cnt) { if (p.first != prime_cnt.begin()->first) cout << "*"; cout << p.first; if (p.second != 1) cout << "^" << p.second; } cout << endl; }
//思路:唯一分解定理裸题。注意几个坑点:当输入为1,输入为素数。 #include <bits/stdc++.h> using namespace std; const int maxn=1e6+5; typedef long long LL; LL n;int vis[maxn]; vector<int> primes; map<int,int> mp; void init(){ int m=sqrt(1e6-100); for(int i=2;i<=m;++i) if(!vis[i]){ for(int j=i*i;j<=maxn-10;j+=i) vis[j]=1; } for(int i=2;i<=maxn-10;++i) if(!vis[i]) primes.push_back(i); } int main(){ init();//cout<<primes.front()<<endl; scanf("%lld",&n);printf("%lld=",n); LL tmp=n; if(n==1) printf("1"),exit(0); for(auto it=primes.begin();it!=primes.end();++it){ while(n%(*it)==0) ++mp[*it],n/=(*it); if(n==1) break; } //cout<<"****"<<endl<<mp[2]<<endl; if(n==tmp) printf("%lld",n),exit(0); if(n!=1) ++mp[n]; int ok=1; for(auto &ch:mp){ if(ok){ ok=0; if(ch.second==1) printf("%d",ch.first); else printf("%d^%d",ch.first,ch.second); }else{ if(ch.second==1) printf("*%d",ch.first); else printf("*%d^%d",ch.first,ch.second); } } return 0; }
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <cmath> using namespace std; bool isPrime(int n) { if(n<=1) return false; if(n==2) return true; for(int i=2;i<=sqrt(n);i++) if(n%i==0) return false; return true; } int main() { int n,t,x=0; int a[30],b[30]; cin>>n; t = n; if(n==1) cout<<"1=1"; else{ int sqr = sqrt(n); for(int i=2;i<=sqr&&n>1;i++) { if(isPrime(i)) if(n%i==0) { a[x] = i; b[x] = 0; while(n%i==0) { b[x]++; n /= i; } x++; } } if(n!=1) { a[x] = n; b[x++] = 1; } cout<<t<<"="; for(int i=0;i<x;i++) { cout<<a[i]; if(b[i]!=1) cout<<"^"<<b[i]; if(i<x-1) cout<<"*"; } } return 0; }
import java.util.Scanner; import java.util.ArrayList; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); System.out.print(n+"="); if(n==1||isPrime(n)){ System.out.println(n); return; } int prime = 2; ArrayList<Integer> list1 = new ArrayList<Integer>(); ArrayList<Integer> list2 = new ArrayList<Integer>(); while(n!=1){ if(n%prime==0){ n /= prime; if(list1.isEmpty()||list1.get(list1.size()-1)!=prime){ list1.add(prime); list2.add(1); }else if(list1.get(list1.size()-1)==prime){ list2.set(list2.size()-1,list2.get(list2.size()-1)+1); } }else if(isPrime(n)){ list1.add(n); list2.add(1); break; }else{ prime = next(prime); } } for(int j = 0;j<list1.size();j++){ System.out.print(list1.get(j)); if(list2.get(j)>1) System.out.print("^"+list2.get(j)); if(j+1!=list1.size()) System.out.print("*"); } } private static boolean isPrime(int a){ int limit = (int)Math.sqrt(a); for(int i = 2;i<=limit;i++) if(a%i==0) return false; return true; } private static int next(int p){ p++; while(!isPrime(p)) p++; return p; } }
解题思路: 本题是正整数n的素因子分解问题。n分为3种情况: (1)n=1,特殊数据,直接按指定格式输出即可。 (2)n是素数,不用分解,直接按指定格式输出即可。要判别n是否为素数,有多种方法,对于本题而言,最简单的方法是使用试商法。因为即使对于n=2147483647=2^31-1范围内的整数,用试商法效率也是很高的,具体参见下面给出的代码。 (3)n是大于1的非素数,这正是本题要完成的工作。可以从最小的素数2开始,依次用2,3,4,5,...,sqrt(n)对n进行分解。当然,如果n很大,对n开平方根后其值也较大,这样循环检测的话,很可能造成程序超时,因为用了一些非素数如4、6、8...等等。当然,可以考虑采用筛法,事先把一定范围内的素数全部筛选出来,存入数组,然后只用这些素数去分解n,效率会相应提高很多。对于本题而言,如果考虑到哪些初学程序设计的同学,因为数组的知识一般在教学过程中比较靠后,所以采用了没有使用数组的方式来完成。参见下面的代码: for(i=2; i<=k; i++) //从最小的素数2开始对n进行分解 { int tot=0; //某个素因子出现的次数(幂指数) if(n%i==0) //i是素因子 { while(n%i==0)//对n进行分解 { tot++; //累计素因子出现的次数 n/=i; //对n进行分解 } //按指定格式打印 ........... } k=(int)sqrt(n+0.0); //更新k的值,这是本题的关键之处 } (4)本题还有一点需要注意,即打印的格式。详细解释参见下面的完整代码: #include<iostream> #include<cmath> using namespace std; //朴素试商法判别n是否为素数 bool is_prime(int n) { if(n<2)return false; int k=(int)sqrt(n+0.0); for(int i=2; i<=k; i++) if(n%i==0)return false; return true; } int main() { int n; while(cin>>n)//循环输入,处理多组数据 { cout<<n<<"="; if(n==1) //处理特殊数据 { cout<<1<<endl; continue; } if(is_prime(n)) //处理素数(不可再分解) { cout<<n<<endl; continue; } int i,k=(int)sqrt(n+0.0);//n的素因子不可能超过k bool first=true; for(i=2; i<=k; i++) //从最小的素数2开始对n进行分解 { int tot=0; //某个素因子出现的次数(幂指数) if(n%i==0) //i是素因子 { while(n%i==0)//对n进行分解 { tot++; //累计素因子出现的次数 n/=i; //对n进行分解 } if(first) //处理n的第1个素因子,按p1^k1的格式打印 { first=false; if(tot>=2)cout<<i<<"^"<<tot;//按幂指数方式打印 else cout<<i; //素因子只出现1次,直接打印该素因子 } else //从第2个素因子开始,按*p2^k2的格式打印 { if(tot>=2)cout<<"*"<<i<<"^"<<tot; else cout<<"*"<<i; } } //某个素因子不能分解n后得到的新的n,新的n的素因子不可能超过k //这是本题的关键之处,即每得到一个新的n,均对其开平方根,否则会超时 k=(int)sqrt(n+0.0); } if(n>1)cout<<"*"<<n; //输出最后一个素因子 cout<<endl; //多组数据之间换行 } return 0; }
更多PAT甲级题解---acking-you.github.io
直接看例子就知道了,就是把N进行质因数分解,然后注意的是有多个相同的质因数时需要把它们以指数形式输出。
unordered_map<int, int> cnt; //记录质因数的次数 vector<int> num; //记录所有质因数
当然你也可以用自己的结构体实现相应的映射。
此时为保证输出有序,应使用map而不是unordered版本。
map<int, int> cnt; //记录质因数和次数的映射关系
bool isPrime(long x) { for (int i = 2; i * i <= x; i++) { if (x % i == 0) return false; } return true; } void solve() { ios::sync_with_stdio(false); cin >> N; cout << N << "="; if (isPrime(N)) { cout << N; return; } int t = N; for (int i = 2; i <= N; i++) { if (t % i == 0) { while (t % i == 0) { cnt[i]++; t /= i; } } if (t == 1) { break; } } }
void handle_one(int a) { //处理单个元素的打印 cout << a; switch (cnt[a]) { case 1: break; default: cout << '^' << cnt[a]; } } void print() { if (cnt.empty()) return; for (auto it = cnt.begin(); it != cnt.end(); ) { handle_one(it->first); it++; if (it != cnt.end()) cout << "*"; } }
两者的效率都差不多,想要进一步提高效率,还是得用原生数组,或者是直接记录。
#include<bits/stdc++.h> using namespace std; long N; map<int, int> cnt; //记录质因数和次数的映射关系 bool isPrime(long x) { for (int i = 2; i * i <= x; i++) { if (x % i == 0) return false; } return true; } void solve() { ios::sync_with_stdio(false); cin >> N; cout << N << "="; if (isPrime(N)) { cout << N; return; } int t = N; for (int i = 2; i <= N; i++) { if (t % i == 0) { while (t % i == 0) { cnt[i]++; t /= i; } } if (t == 1) { break; } } } void handle_one(int a) { //处理单个元素的打印 cout << a; switch (cnt[a]) { case 1: break; default: cout << '^' << cnt[a]; } } void print() { if (cnt.empty()) return; for (auto it = cnt.begin(); it != cnt.end(); ) { handle_one(it->first); it++; if (it != cnt.end()) cout << "*"; } } int main() { solve(); print(); return 0; }
#include<bits/stdc++.h> using namespace std; int main(){ int m; int flag=0; while(cin>>m){ // int count=0; if(m==1){ cout<<"1=1"<<endl; continue; } cout<<m<<"="; for(int j=2;j*j<=m;j++){ if(m%j==0){ flag++; if(flag==1){ cout<<j; } else cout<<"*"<<j; } int count=0; while(m%j==0){ m=m/j; count++; } if(count>1){ cout<<"^"<<count; } if(m<=1) break; } if(m!=1&&flag!=0){ cout<<"*"<<m; }else if(m!=1&&flag==0){ cout<<m; } cout<<endl; } }思路很简单,就是输出格式上坑了几次
#include<bits/stdc++.h> using namespace std; int main(){ int n; while(~scanf("%d",&n)){ map<int,int> mp; int temp=n; if(n==1)printf("1=1"); else{ for(int i=2;i<sqrt(n);i++){ if(n%i==0){ while(n%i==0){ mp[i]++; n/=i; } } } if(n!=1)mp[n]++; printf("%d=",temp); int count=0; for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++){ if(it->second>1){ printf("%d^%d",it->first,it->second); }else if(it->second==1){ printf("%d",it->first); } count++; if(count!=mp.size()){ printf("*"); }else{ printf("\n"); } } } } return 0; }
#include<iostream> (720)#include<vector> #include<limits.h> (1124)#include<cmath> using namespace std; const int MAXN = 1e6; bool prime[MAXN]; vector<int>primeFactors; vector<int>indexofPrime; void getPrime() { prime[0] = false; prime[1] = false; for (int i = 2; i < MAXN; i++) { if (!prime[i]) { continue; } for (int j = i * i; j < MAXN; j += i) { prime[j] = false; } } } int main() { fill(prime, prime + MAXN, true); getPrime(); int n; cin >> n; int up = sqrt(n); int tmp = n; for (int i = 2; i < MAXN; i++) { if (prime[i]) { int num = 0; while (tmp % i == 0) { num++; tmp /= i; } if (num != 0) { primeFactors.push_back(i); indexofPrime.push_back(num); } } if (tmp == 1) { break; } } printf("%d=", n); for (int i = 0; i < primeFactors.size(); i++) { if (i) printf("*"); printf("%d", primeFactors[i]); if(indexofPrime[i]!=1){ printf("^%d",indexofPrime[i]); } } if (primeFactors.empty()){printf("%d", n);}//n本身是一个质数 if(!primeFactors.empty()&&tmp!=1){//n分解后还存在一个大于1e6的质数 printf("*%d",tmp); } }
a = int(input()) d = {};m = [];b = a while True: for i in range(2,int(a ** 0.5) + 1): if a / i == a // i: a /= i d[i] = d[i] + 1 if i in d else 1 break else: d[int(a)] = d[int(a)] + 1 if int(a) in d else 1 break for i in sorted(d): m.append((str(i) + '^' + str(d[i])) if d[i] > 1 else str(i)) print(str(b) + '=' + '*'.join(m))
/* 改了很多次才通过,代码显得很凌乱 一开始的只是简单的穷举,提交后超时,所以改成了这种方法 我的思路是这样: 伪代码: cin>>n; for i to sqrt(n): if i 是素数: 存入结果i,i次数为1 n=n/i while n%i==0: i次数+1 n/=i 最后n要么是1,要么是一个素数 n=1有两种情况:1.输入的即是1;2.连除后得到1 前一种情况按照要求输出1即可 若n不为1,即n为素数,则结果中加入n即可 代码没有整理,看了一下评论,后面有一位‘巴黎的夜雪’的代码思路和我一样,且更简洁易懂,若有兴趣的看他的即可 */ #include<iostream> using namespace std; int main() { long N; while (cin >> N) { long n = N; int num = 0; long prime[50]; //long int小于2^31,大于31即不会越界 int amount[50]; int num2 = 0; for (long i = 2; i * i <= n; i++) { if (n%i == 0) { bool istrue = true; for (long j = 2; j <= long(sqrt(i)); j++) { if (i%j == 0) { istrue = false; break; } } if (istrue) { prime[num] = i; amount[num] = 1; n = n / i; while (true) { if (n%i == 0) { amount[num] += 1; n = n / i; } else { break; } } num++; } num2++; } } cout << N << "="; if (num2==0||n!=1) { prime[num] = n; amount[num] = 1; num++; } for (int i = 0; i < num - 1; i++) { if (amount[i] > 1) { cout << prime[i] << "^" << amount[i] << "*"; } else { cout << prime[i] << "*"; } } if (amount[num - 1] > 1) { cout << prime[num - 1] << "^" << amount[num - 1]; } else { cout << prime[num - 1]; } cout << endl; } return 0; }
n = input() n = int(n) backup = int(n) if n==1: print('1=1') else: i = 2 lst,out = [],[] while n>1: if n%i==0: lst.append(i) n= n//i else: if i<=n**0.5: i+=1 else: i = int(n) out = sorted(set(lst)) print(str(backup)+'=',end='') for i in range(0,len(out)-1): if lst.count(out[i])>1: print(str(out[i])+'^'+str(lst.count(out[i]))+"*",end='') else: print(str(out[i])+"*",end='') if lst.count(out[len(out)-1])>1: print(str(out[len(out)-1])+'^'+str(lst.count(out[len(out)-1]))) else: print(str(out[len(out)-1]))
x=input()
p,q,n,i=[1],[1],int(x),2
while n!=1:
if n%i==0:
if i==p[-1]:
q[-1]+=1
else:
p.append(i)
q.append(1)
n/=i
else:
i=int(n) if i>n**0.5 else i+1
res=[] if int(x)!=1 else ['1']
for i in range(1,len(p)):
if q[i]==1:
res.append(str(p[i]))
else:
res.append(str(p[i])+'^'+str(q[i]))
print(x+'='+'*'.join(res))
思路: 用map存储因子的个数。然后按照格式输出。 #include <iostream> #include <map> #include <math.h> #include <fstream> using namespace std; #ifndef Debug ifstream ifile("case.txt"); #define cin ifile #endif bool Prime(long long x) { bool check = true; if (x == 2) return check; for (int i = 2; i <= sqrt(x); i++) { if (x % i == 0) { check = false; break; } } return check; } void GenMap(int n, map<int,int> & mp) { if (n == 1|| Prime(n)) { mp[n]++; return; } long long muti = 1; for (int i = 2; i <=n; ) { if (!Prime(i)) { i++; } if (n % i == 0)// i是他的因子 { n = n / i; mp[i]++; } else i++; } } int main() { long long n; cin >> n; map<int,int> mp; GenMap(n, mp); cout << n << "="; for (map<int, int>::iterator it = mp.begin(); it != mp.end(); it++) { if (it == mp.begin()) { cout << it->first; if (it->second > 1) { cout << "^" << it->second; } } else { cout << "*" <<it->first; if (it->second > 1) { cout << "^" << it->second; } } } system("pause"); }