问题描述
求出区间[a,b]中所有整数的质因数分解。
输入格式
输入两个整数a,b。
输出格式
每行输出一个数的分解,形如k=a1*a2*a3...(a1<=a2<=a3...,k也是从小到大的)(具体可看样例)
样例输入
3 10
样例输出
3=3
4=2*2
5=5
6=2*3
7=7
8=2*2*2
9=3*3
10=2*5
提示
先筛出所有素数,然后再分解。
数据规模和约定
2<=a<=b<=10000
Java代码(虽然能运行出结果,但数据稍大时很容易运行超时):
import java.util.*;
public class Main {
public static boolean solve1(int x){//判断质数
int i=2;
for(;;i++){
if(x%i==0)
break;
}
if(i==x)
return true;
else
return false;
}
public static int[] solve2(int l){//构造质数表
int[] a=new int[l];
a[0]=2;
for(int i=1;i<l;i++){
for(int j=a[i-1]+1;;j++){
if(solve1(j)){
a[i]=j;
break;
}
}
}
return a;
}
public static void main(String[] args) {//运行超时!!
Scanner in=new Scanner(System.in);
int a=in.nextInt(),b=in.nextInt();
int l=b-a+1;
int[] arr=solve2(l);
for(int i=a;i<=b;i++){
if(solve1(i))//是质数
System.out.println(i+"="+i);
else{//不是质数
List<Integer> list=new ArrayList<Integer>();
int x=i;
while(x!=1){
for(int j=0;j<arr.length;j++){
if(x%arr[j]==0){
list.add(arr[j]);
x/=arr[j];
break;
}
}
}
int[] c=new int[list.size()];
for(int j=0;j<list.size();j++)
c[j]=list.get(j);
for(int p=0;p<c.length-1;p++){//冒泡排序
for(int q=0;q<c.length-p-1;q++){
if(c[q]>c[q+1]){
int temp=c[q];c[q]=c[q+1];c[q+1]=temp;
}
}
}
System.out.print(i+"="+c[0]);
for(int j=1;j<c.length;j++){
if(j==c.length-1)
System.out.println("*"+c[j]);
else
System.out.print("*"+c[j]);
}
}
}
}
}
Python代码:
import math
def is_prime(x):
if x<2:
return False
elif x==2:
return True
else:
for i in range(2,int(math.sqrt(x))+1):
if x%i==0:
return False
return True
a,b=map(int,input().split())
l=[] # 质数列表
# 填充列表
for i in range(2,b+1):
if is_prime(i):
l.append(i)
# print(l)
# 分解
for i in range(a,b+1):
x=i
print(x,end="=")
j=0
first=True # 是否为第一个质因数
while x!=1:
if x%l[j]==0: # l[j]是x的质因数
if first==True: # 是第一个质因数
print(l[j],end="")
first=False
else: # 不是第一个质因数
print("*"+str(l[j]),end="")
x/=l[j]
j=0
else:
j+=1
print()
这道题主要是对逆向思维的一个考察:
题目要求我们分解出一个数的所有质因数,如果我们一味地思考一个数的质因数有哪些,只会南辕北辙;正确的思路应该是先构建一个质数表,从小到大一次次地遍历并选出它的质因数。
还有一点,判断n是不是质数只需要检查2~的所有整数即可。
其中有一处关于ArrayList返回数组的知识点之前多次遇到,在此总结一下:
(ArrayList<Integer>如何转换为int[]数组_huanghanqian的博客-CSDN博客引自博主huanghanqian)
网上搜Arraylist和数组互相转换的方法时,举的例子都是String类型的。比如:
但是对于int类型如果这样写:
ArrayList<Integer> list=new ArrayList<Integer>();
int[] array=(int[])list.toArray(new int[size]);//会报错
则会报错,这是因为int[]并不等同于Integer[](Integer是int的一个包装类)。因此如果换成Integer[]数组,则能正确运行。
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
Integer[] array = list.toArray(new Integer[list.size()]);//能正确运行
for(int element:array)
System.out.println(element);
如果非得希望得到int[]的话,只能用循环赋值来得到了。
int[] arr = new int[list.size()];
for(int i = 0;i<list.size();i++)
arr[i] = list.get(i);
如果既不想用循环,又想要得到int[],那就只能在jdk8中使用IntStream了。