昨天又AC了一道题,之前一直没注意算法,现在觉得算法简直弱爆了。来看看题目要求:
我没想到比较简单的算法,只好用暴力破解了.而且代码还很长。虽然最后运行的时候运行超过1s了,但是这样去想过算法之后,收获才是最大的,也就是说拿到一道算法题不要急着去网上找算法,找答案,然后照着写,这样对自己没多大好处。
我第一次写的算法:
import java.util.Scanner;
import java.util.Stack;
class day_0111_01{
private static int x;
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
Stack<Integer> sc = new Stack<Integer>();
int[] a =new int[6];
int [] b= new int[5];
if(n<1||n>54){
n =scan.nextInt();
}
for(int i=999999;i>=10000;i--){
int j =i;
if(j>99999){
for(x=5;x>=0;x--){
int c =(int)Math.floor(j/Math.pow(10, x));//floor()的返回值为double类型的,所以要强制转换为int类型再赋值给c
j =(int)(j%Math.pow(10, x));
a[x]=c;
}
if(n==a[0]+a[1]+a[2]+a[3]+a[4]+a[5]&&a[0]==a[5]&&a[1]==a[4]&&a[2]==a[3])
sc.push(i);
}
else
{
for(x=4;x>=0;x--){
int d =(int)Math.floor(j/Math.pow(10, x));
j =(int)(j%Math.pow(10, x));
b[x]=d;
}
if(n==b[0]+b[1]+b[2]+b[3]+b[4]&&b[0]==b[4]&&b[1]==b[3])
sc.push(i);
}
}
while(!sc.isEmpty()){
System.out.println(sc.peek());
sc.pop();
}
}
}
首先我用了两个数组a[6]和b[5]来存放六位和五位的回文数。拿六位数回文数为例,把六位数的每个位上的数字取出放入数组中,进行判定后把符合要求的数压入栈中保存。
用我自己写的这种方法虽然也能达到相同的目的,但是运行时间太长,而且占用的内存较多。所以初学算法,自己写了再看看别人有经验的人写的,提高才是非常大的。
下面看看我找到的一个比较好的算法,学习了。
import java.util.Arrays;
import java.util.Scanner;
class day_0111_03{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int i,j,k,n;
int[][] gre = new int[60][1000];
for(n=1;n<=54;n++)
{ int f=0;
for(i=1;i<=9;i++)
for(j=0;j<=9;j++)
for(k=0;k<=9;k++){
if(i+j+k+j+i==n)
gre[n][f++] =Integer.valueOf(i+""+j+""+k+""+j+""+i);
if(2*(i+j+k)==n)
gre[n][f++] =Integer.valueOf(i+""+j+""+k+""+k+""+j+""+i);
}
}
while(sc.hasNext()){
int m =sc.nextInt();
Arrays.sort(gre[m]);
for(i=0;i<1000;i++){
if(gre[m][i]!=0)
System.out.println(gre[m][i]);
}
}
}
}
由于回文数是对称的,所以他只定义了3个变量i,j,k来存每一位上的数据。这个算法真的很巧妙,之前我也想用循环嵌套循环的方法来写,但是我总觉得上了3重循环之后
运行时间一定很长,看来这个想法也不置可否。
如下这种把五位数六位数全部扫一遍的方式确实很耗时间
for(int i=999999;i>=10000;i--)
现在有一种可以借鉴的方法来避免全扫一遍数据
for(i=1;i<=9;i++)
for(j=0;j<=9;j++)
for(k=0;k<=9;k++)
这样耗时就要小得多了。