算法训练之暴力枚举

一,四叶玫瑰

如果一个 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);
	}

}


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值