猜算式
- 题目:
看下面的算式:
□□ x □□ = □□ x □□□
它表示:两个两位数相乘等于一个两位数乘以一个三位数。
如果没有限定条件,这样的例子很多。
但目前的限定是:这9个方块,表示1~9的9个数字,不包含0。
该算式中1至9的每个数字出现且只出现一次!
比如:
46 x 79 = 23 x 158
54 x 69 = 27 x 138
54 x 93 = 27 x 186
.....
请编程,输出所有可能的情况!
注意:
左边的两个乘数交换算同一方案,不要重复输出!
不同方案的输出顺序不重要 - 思路:
- 注意:显示的数字不可以重复,两个乘数交换算一种,不可以重复。
- 两种方法:9个for循环,并且要判断不可以重复的,进行剪枝,全排列。
- 代码:(9个for循环)
public void solve1() {
long start=System.currentTimeMillis();
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= 9; j++) {
if (j == i)
continue;
for (int k = 1; k <= 9; k++) {
if (k == i || k == j)
continue;
for (int l = 1; l <= 9; l++) {
if (l == k || l == i || l == j)
continue;
for (int m = 1; m <= 9; m++) {
if (m == l || m == k || m == i || m == j)
continue;
for (int n = 1; n <= 9; n++) {
if (n == k || n == i || n == j || n == m
|| n == l)
continue;
for (int o = 1; o <= 9; o++) {
if (o == k || o == i || o == j || o == n
|| o == m || o == l)
continue;
for (int p = 1; p <= 9; p++) {
if (p == k || p == i || p == j
|| p == o || p == n || p == m
|| p == l)
continue;
for (int q = 1; q <= 9; q++) {
if (q == k || q == i || q == j
|| q == o || q == n
|| q == m || q == l
|| q == p)
continue;
if ((i * 10 + j) * (k * 10 + l) == (m * 10 + n)
* (o * 100 + p * 10 + q)) {
if(!al.contains(i * 10 + j)){
//去掉重复的操作,因为9个for的话,一定是从小到大的,比较第一个小的,存最后一个大的
System.out
.println((i * 10 + j)
+ "*"
+ (k * 10 + l)
+ "=="
+ (m * 10 + n)
+ "*"
+ (o * 100 + p
* 10 + q));
al.add(k * 10 + l);
}
}
}
}
}
}
}
}
}
}
}
System.out.println(System.currentTimeMillis()-start);
}
这个虽然是暴力,但是很快。
代码二(全排列,按自己的思想,用了10多秒)
//初始化
char[] chArr=new char[]{'1','2','3','4','5','6','7','8','9'};
StringBuffer sb=new StringBuffer(String.valueOf(chArr));
ArrayList<Integer> al=new ArrayList<Integer>();
public void solve2(){
long start=System.currentTimeMillis();
permutation(chArr,0,8);
System.out.println(System.currentTimeMillis()-start);
}
//全排列
public void permutation(char[] chArr,int first,int end){
if(first==end){
sb.replace(0, 8, String.valueOf(chArr));
isPrint(sb);
}
for(int i=first;i<=end;i++){
swap(chArr, i, first);
permutation(chArr, first+1, end); //固定一个,其他的进行交换
swap(chArr, i, first);
}
}
//判断是否符合条件,进行输出
public void isPrint(StringBuffer sb){
String str=sb.toString();
int a=Integer.valueOf((str.substring(0, 2)));
int b=Integer.valueOf((str.substring(2, 4)));
int n=Integer.valueOf((str.substring(4, 6)));
int m=Integer.valueOf((str.substring(6, 9)));
if(a*b==n*m){
if(!al.contains(a)){
System.out.println(a+"*"+b+"="+n+"*"+m);
al.add(b);
}
}
}
//进行交换
public void swap(char[] chArr,int first,int end){
char tmp=chArr[first];
chArr[first]=chArr[end];
chArr[end]=tmp;
}
带条链接:全国软件大赛(猜算式)全排列实现