算法之枚举

什么是枚举?枚举就是有序的去尝试每一种可能。

举个例子,小学的奥数题,求  _3*6541=3_*8526, 做这道题时我们应该从第一位依次尝试从1到9,第空也依次尝试,寻找满足条件的情况。

问题:求  ___ + ___ = ___   的所有可能,将数字1-9分别填入这9个_中,每个数字只能使用一次。

有的同学可能会直接嵌套九个循环分别从1-9枚举每一位,然后再加判断条件 a!=b && a!=c&& a!=d.........&& a*100+b*10+c + d*100+e*10+f = g*100+h*10+i,使用九个变量会比较浪费内存,这里我们可以用一个数组来代替,代码如下:

public class MeiJu1 {

	public static void main(String[] args) {
		int[] a = new int [10];
		int total = 0,sum;
		int[] book = new int[10];
		//这里用a[1]-a[9]代替a-i
		for(a[1] = 1; a[1]<=9; a[1]++)
			for(a[2] = 1; a[2]<=9; a[2]++)
				for(a[3] = 1; a[3]<=9; a[3]++)
					for(a[4] = 1; a[4]<=9; a[4]++)
						for(a[5] = 1; a[5]<=9; a[5]++)
							for(a[6] = 1; a[6]<=9; a[6]++)
								for(a[7] = 1; a[7]<=9; a[7]++)
									for(a[8] = 1; a[8]<=9; a[8]++)
										for(a[9] = 1; a[9]<=9; a[9]++){
											for(int i=1; i <=9; i++){//初始化book[]数
                                                                       组
												book[i] = 0;
											}
											for(int i=1; i <= 9; i++){//哪个数出现过就
                                                                         标记一下
												book[a[i]] = 1;
											}
											sum=0;
											for(int i=1;i<=9; i++){//统计共出现过多少个
                                                                     不同的数
												sum+=book[i];
											}
											//如果刚好出现九个数且满足条件,就输出,可能性
                                          total+1
											if(sum ==9 && a[1]*100+a[2]*10+a[3] + 
                                                 a[4]*100+a[5]*10+a[6] == 
													a[7]*100+a[8]*10+a[9]){
												total++;
												
                   System.out.println(a[1]+""+a[2]+""+a[3]+"+"+a[4]+""+a[5]+""+a[6]
														+"+"+a[7]+""+a[8]+""+a[9]);
											}
										}
      System.out.println("total:"+total);		
	}
}

问题2:火柴棍等式

给定n根火柴棍,希望拼出形如A+B=C的等式,等式中的A B C均是用火柴棍拼出来的整数,数字0-9所需根数为{6,2,5,5,4,5,6,3,7,6},加号和等于号各需要两根火柴,例如14根火柴可以拼成 0+1=1 和 1+0=1,18根火柴可以拼成 0+4=4,0+11=11,1+10=11,2+2=4,2+7=9,4+0=4,7=2=9,10+1=11,11+0=11,本题最多火柴数是24,代码如下:

import java.util.Scanner;

public class MeiJu2 {

	public static int fun(int x){
		int num = 0;//用来计数的变量,初始化
		//这个数组用来记录每个数需要的火柴棍根数
		int f[] = {6,2,5,5,4,5,6,3,7,6};
		//如果这个数大于10,即对10取余得到个位(十位/百位)数,先加上个位数的火柴数 
		while(x/10!=0){
			num+=f[x%10];
			x/=10;//去掉个位,(十位/百位)
		}
		num+=f[x];//加上最大一位的火柴数
		return num;
	}
	public static void main(String[] args) {
		int c,sum=0,m;
		Scanner sc = new Scanner(System.in);
		m = sc.nextInt();//读入火柴数,本题最大火柴根数是24
		//减去加号和减号各两根,还剩下20根,而最少的数字1是占两根,最多有十个1,每个数不能超过1111
		for(int a=0; a<=1111; a++){
			for(int b=0; b<=1111; b++){
				c = a+b;
				//如果三个数加起来的火柴数刚好等于输入的根数减去4,则满足
				if(fun(a) + fun(b)+fun(c) == m-4){
					System.out.println(a+"+"+b+"="+c);
					sum++;
				}
			}
		}
	    System.out.println("一共可以拼出"+sum+"个等式");
	    sc.close();
	}
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值