《啊哈算法》的Java实现 | 第六章 :最短路径及最短路径算法的对比分析.
坑爹的奥数
枚举算法的基本思想就是:有序地去尝试每一种可能
package ch3;
/*
每一个数的个位十位百位上可能出现的数字都遍历一遍
*/
public class enumerationTest01 {
public static void main(String[] args) {
int[] book = new int[10];//定义一个用来标记的数组
int[] a= new int[10];//用来代替 三个数的百分位、十分位、个位
int total = 0;//一共有多少个等式成立
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中的值表示a[i]中的值,出现的次数
book[i] = 0;
}
for(int i =1;i<=9;i++){//如果某个数出现就标记一下
book[a[i]] = 1;
}
//统计一共出现了多少不同的数
int sum = 0;
for (int i = 1;i<=9;i++){
sum+=book[i];
}
//如果正好出现了9个不同的数,并且满足等式的台哦见,则输出
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.printf("%d%d%d+%d%d%d=%d%d%d\n",a[1], a[2],
a[3], a[4],
a[5], a[6],
a[7], a[8],
a[9]);
}
}
}
}
}
}
}
}
}
}
System.out.println("总共有:" + total /2);
}
}
炸弹人
核心思想为:分别统计上下左右四个方向的敌人
x++
x--
y++
y--
package ch3;
import java.util.Scanner;
public class enumerationTest02 {
public static void main(String[] args) {
char[][] chars = {
{'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'},
{'#', 'G', 'G', '.', 'G', 'G', 'G', '#', 'G', 'G', 'G', '.', '#'},
{'#', '#', '#', '.', '#', 'G', '#', 'G', '#', 'G', '#', 'G', '#'},
{'#', '.', '.', '.', '.', '.', '.', '.', '#', '.', '.', 'G', '#'},
{'#', 'G', '#', '.', '#', '#', '#', '.', '#', 'G', '#', 'G', '#'},
{'#', 'G', 'G', '.', 'G', 'G', 'G', '.', '#', '.', 'G', 'G', '#'},
{'#', 'G', '#', '.', '#', 'G', '#', '.', '#', '.', '#', '#', '#'},
{'#', '#', 'G', '.', '.', '.', 'G', '.', '.', '.', '.', '.', '#'},
{'#', 'G', '#', '.', '#', 'G', '#', '#', '#', '.', '#', 'G', '#'},
{'#', '.', '.', '.', 'G', '#', 'G', 'G', 'G', '.', 'G', 'G', '#'},
{'#', 'G', '#', '.', '#', 'G', '#', 'G', '#', '.', '#', 'G', '#'},
{'#', 'G', 'G', '.', 'G', 'G', 'G', '#', 'G', '.', 'G', 'G', '#'},
{'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'}
};
int n = 10;
int m = 10;
//char[][] chars = new char[20][20];//创建一个20*20的地图
int sum,map = 0;
int x,y,p = 0,q = 0;//辅助变量
/*Scanner scanner = new Scanner(System.in);
System.out.println("输入有多少行:");
int n = scanner.nextInt();
System.out.println("输入有多少列:");
int m = scanner.nextInt();*/
//读入n行字符
/*for (int i = 0; i<n ;i ++){
String s= scanner.nextLine();
}*/
//利用两重循环枚举地图中的每一个点
for (int i =0;i<n;i++){
for (int j = 0; j <m; j++){
//首先判断这个点是否为平地
if (chars[i][j] == '.') {
sum = 0;//用来记录消灭敌人的总数
//当前左边为i,j,复制到两个新的变量x,y中,以便上下左右四个方法风别统计
//向上可以消灭的敌人数
x = i;
y = j;
while(chars[x][y] != '#'){//判断不是墙
if(chars[x][y] == 'G')
sum ++ ;//如果是敌人就+1
x --; //继续向上统计
}
//向下统计
x = i;
y = j;//回到炸弹点
while(chars[x][y] != '#'){
if(chars[x][y] == 'G')
sum++;
x ++;
}
//向左统计
x = i;
y = j;//回到炸弹点
while(chars[x][y] != '#'){
if(chars[x][y] == 'G')
sum++;
y --;
}
//向右统计
x = i;
y = j;//回到炸弹点
while(chars[x][y] != '#'){
if(chars[x][y] == 'G')
sum++;
y ++;
}
//更新map的值
if (sum > map){
map = sum;
//记录当前点的位置
p = i;
q = j;
}
}
}
}
System.out.println("做多可以消灭的地人数:" + map);
System.out.println("坐标点为:" + p + "," + q);
}
}
火柴棍等式
package ch3;
import javax.swing.plaf.synth.SynthEditorPaneUI;
import java.util.Scanner;
public class enumerationTest03 {
public static void main(String[] args) {
int c,sum = 0;
Scanner scanner = new Scanner(System.in);
System.out.println("请输入火柴数目:");
int m = scanner.nextInt();
for (int i = 0; i<= 1111;i++){
for(int j = 0; j <= 1111;j++){
c = i+j;
if (fun(i) + fun(j) + fun(c) == m-4){
System.out.println(i + "+" + j + " = " + c);
sum ++;
}
}
}
System.out.println("总共成立的等式为:" + sum);
}
public static int fun(int x){
int num = 0;//用来记录火柴的根数
int[] number = {6,2,5,5,4,5,6,3,7,6};
//当x/10不为0的时候,那么x必定最少为2位数
while(x/10 != 0){
//取出最后一位数
int last = x % 10;
num += number[last];//更新火柴数
x = x/10;
}
//循环结束后,只剩下一位数
num += number[x];
return num;
}
}