我是靠谱客的博主 英俊鲜花,最近开发中收集的这篇文章主要介绍算法训练之暴力枚举,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一,四叶玫瑰

如果一个 44 位数,它的每个位上的数字的 44 次幂之和等于它本身,那么我们就称这个数字为一个四叶玫瑰数。现在,我们要求出所有的四叶玫瑰数


public class test1 {
	public static void main(String[] args) {
		for(int i =1000;i<10000;i++){
			int a = i%10;
			int b = i%100/10;
			int c = i/100%10;
			int d = i/1000;
			if(a*a*a*a+b*b*b*b+c*c*c*c+d*d*d*d==i)
				System.out.print(i+" ");
		}
	}

}

二, 

观察数字:1232112321123321123321 都有一个共同的特征,就是无论从左到右读还是从右向左读,都是相同的。这样的数字叫做 回文数字

现在要从 55 位或 66 位的十进制数字中找出各个数位之和等于 nn 的回文数字。

输入格式

输入一个整数 n(10 leq n leq 100)n(10n100)

输出格式

输出所有各个数位之和等于 nn 的 55 位和 66 位整数,每个数字占一行,数字按从小到大的顺序排列。如果没有满足条件的数字,则输出 -11

import java.util.Scanner;

public class test2 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int sum = 0;
		int n = sc.nextInt();
		for(int a=1;a<=9;a++)
			for(int b=0;b<=9;b++)
				for(int c=0;c<=9;c++){
					if(a*2+b*2+c==n){
						System.out.println(""+a+b+c+b+a);
						sum++;
					}
				}
		for(int a=1;a<=9;a++)
			for(int b=0;b<=9;b++)
				for(int c=0;c<=9;c++){
					if(a*2+b*2+c*2==n){
						System.out.println(""+a+b+c+c+b+a);
						sum++;
					}
				}
		if(sum==0)
			System.out.println(-1);
	}
}

三,方程的解

方程: a^2 + b^2 + c^2 = 1000a2+b2+c2=1000,其中 a < b < ca<b<c。我们知道这个方程有两组正整数解,其中 a,b,c=6,8,30a,b,c=6,8,30 就是一组解。你能算出另一组正整数解吗?

public class test7 {
	public static void main(String[] args) {
		for(int a=1;a<=100;a++)
			for(int b=a+1;b<=100;b++)
				for(int c=b+1;c<=100;c++)
				{
					if(a*a+b*b+c*c==1000)
						System.out.println(""+a+" "+b+" "+c);
				}
	}
}

四,最大子阵

给定一个 n times mn×m 的矩阵 AA,求 AA 中的一个非空子矩阵,使这个子矩阵中的元素和最大。其中,AA 的子矩阵指在 AA 中行和列均连续的一部分。

输入格式

输入的第一行包含两个整数 n,m(1 leq n,m leq 50)n,m(1n,m50),分别表示矩阵 AA 的行数和列数。接下来 nn 行,每行 mm 个整数,表示矩阵 A_{i,j}(-1000 leq A_{i,j} leq 1000)Ai,j(1000Ai,j1000)

输出格式

输出一行,包含一个整数,表示 AA 中最大的子矩阵中的元素和。

样例输入
3 3
2 -4 1
-1 2 1
4 -2 2
样例输出
6
import java.util.Scanner;

public class test8_Enum {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n= sc.nextInt();
		int m = sc.nextInt();
		int[][] a = new int[n+1][m+1];
		
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++){
				a[i][j]=sc.nextInt();
			}
		int ans = -1000;
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
				for(int ti=i;ti<n;ti++)
					for(int tj=j;tj<m;tj++)//枚举子集
					{
						int sum=0;
						for(int ii=i;ii<=ti;ii++)
							for(int jj=j;jj<=tj;jj++){
								sum+=a[ii][jj];
							}
						if(ans<sum)
							ans=sum;
					}
		System.out.println(ans);
			
	}

}

五,四平

四平方和定理,又称为拉格朗日定理:每个正整数都可以表示为至多 44 个正整数的平方和。如果把 00 包括进去,就正好可以表示为 44 个数的平方和。

比如:

displaystyle 5 = 0^2 + 0^2 + 1^2 + 2^25=02+02+12+22

displaystyle 7 = 1^2 + 1^2 + 1^2 + 2^27=12+12+12+22

则对于一个给定的正整数 nn,可以表示为:n = a^2 + b^2 + c^2 + d^2n=a2+b2+c2+d2

你需要求出字典序最小的一组解 a,b,c,da,b,c,d

字典序大小:从左到右依次比较,如果相同则比较下一项,直到有一项不同,较小的一方字典序更小,反之字典序更大,所有项均相同则二者字典序相同。

输入格式

程序输入为一个正整数 N(1 leq N leq 5000000)N(1N5000000)

输出格式

输出 44 个非负整数 a,b,c,da,b,c,d,中间用空格分开。

样例输入1
5
样例输出1
0 0 1 2
样例输入2
12
样例输出2
0 2 2 2
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		for(int a=0;a<=(int)Math.sqrt(n);a++)
			for(int b=a;b<=(int)Math.sqrt(n);b++)
				for(int c=b;c<=(int)Math.sqrt(n);c++)
					{
						int d = (int)Math.sqrt(n-a*a-b*b-c*c);
						if(a*a+b*b+c*c+d*d==n && d>=c){	
							System.out.println(a+" "+b+" "+c+" "+d);
							return;
						}
					}
	}
}


六,得到整数X//这里找不到枚举写法代码,有空补上

某君有 nn 个互不相同的正整数,现在他要从这 nn 个正整数之中无重复地选取任意个数,并仅通过加法凑出整数 XX。求某君有多少种不同的方案来凑出整数 XX

输入格式

第一行,输入两个整数 n,X(1 leq n leq 20, 1 leq X leq 2000)n,X(1n20,1X2000)

接下来输入 nn 个整数,每个整数不超过 100100

输出格式

输出一个整数,表示能凑出 

XX 的方案数。

样例输入
6 6
1 2 3 4 5 6
样例输出
4
import java.util.Scanner;

public class Main {

	static int N,X;
	static int res=0,sum=0;
	static int[] a = new int[22];
	static void dfs(int n,int sum){
		if(n>N)
			return;
		if(n==N && sum==X){
			res++;
			return;
		}

		dfs(n+1,sum+a[n]);
		dfs(n+1,sum);
		
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		N=sc.nextInt();
		X=sc.nextInt();
		for(int i=0;i<N;i++){
			a[i]=sc.nextInt();
		}
		dfs(0,sum);
		System.out.println(res);
	}

}

七,李白打酒

话说大诗人李白,一生好饮。幸好他从不开车。

一天,他提着酒壶,从家里出来,酒壶中有酒两斗。他边走边唱:

  • 无事街上走,提壶去打酒。
  • 逢店加一倍,遇花喝一斗。

这一路上,他一共遇到店 55 次,遇到花 1010 次,已知最后一次遇到的是花,他正好把酒喝光了。请你计算李白遇到店和花的次序,有多少种可能的方案

这个题目解法很多,二进制枚举是一种写起来非常简洁的解法。
我们已知遇店 5 次,遇花 10 次,并且最后一次遇到花,正好把酒喝光。
那么我们可以把店作为二进制中的 1,把花作为二进制中的 0,
因为已经确定最后一次遇到的是花,所以我们需要判断枚举的结果是否刚好有 5个 1 和 9 个 0。
那么我们就枚举出 14 位二进制的所有可能并加以判断即可,判断思路为判断二进制是否有 9 个 0,5 个 1
并且最终酒刚好剩 1斗。

public class test9 {

	public static void main(String[] args) {
		int ans = 0;
		for(int i=0;i<(1<<14);++i){//个数
			int sum_1 = 0;
			int sum_0 = 0;
			int num = 2;
			for(int j=0;j<14;++j){
				if((i&(1<<j))>0){//第j+1位不是0
					sum_1++;
					num*=2;
				}
				else{
					sum_0++;
					num-=1;
				}
			}
			if(sum_1==5 && sum_0==9 && num==1)
				++ans;
		}
		System.out.println(ans);
	}

}


最后

以上就是英俊鲜花为你收集整理的算法训练之暴力枚举的全部内容,希望文章能够帮你解决算法训练之暴力枚举所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(35)

评论列表共有 0 条评论

立即
投稿
返回
顶部