蓝桥杯 特殊回文数的查找

昨天又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++)
这样耗时就要小得多了。
 

猜你喜欢

转载自blog.csdn.net/msdumin/article/details/18178073
今日推荐