纸牌三角形
A,2,3,4,5,6,7,8,9 共9张纸牌排成一个正三角形(A按1计算)。要求每个边的和相等。
下图就是一种排法(如有对齐问题,参看p1.png)。
A
9 6
4 8
3 7 5 2
这样的排法可能会有很多。
如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?
请你计算并提交该数字。
注意:需要提交的是一个整数,不要提交任何多余内容。
方法一:
这道题第一次看到,便想到是一个全排列的题,关键点在于如何保证全部的情况都考虑到,并且每种排列情况互不影响程序的进行。
那我的思路是直接抽象为一个9长度的一位数组,进行全排列。当然从1 2 3 4 5 6 7 8 9
这里用一个少的例子,先自己找找全排列的规律
A B C D
A B D C
A C B D
A C D B
A D C B
A D B C
B…
ok ,其实很自然地可以看到是从A开始判断过后,直接进行下一位B的判断一直到D…
然后在找到D过后 直接输出ABCD,然后再反着来从D开始全排列,
D排列完了就从ABCD这个原始数据的C开始进行向D的全排列 ,得到ABDC
然后就又从ABCD的原始数据的B开始向后全排列…一直进行下去。
到这里不难想到就是利用递归。但是关键点在于递归的参数值和递归结束的标志。
看代码,不断学习吧。
import java.util.Scanner;
public class Main{
private static int count = 0; //用这个来存储满足的情况
public static void main(String[] args) {
int[] a= {1,2,3,4,5,6,7,8,9};
Sq(a, 0);
System.out.println(count/6);//**为什么要除以6,因为我们是全排列,而题目要求 三角形旋转(3倍),镜像(2倍)算一种**
//最后要除以6!!!!!!!
}
public static void Sq(int[] data, int k) { //k代表当前的可以与后面的数字交换的位置
if(k==data.length) { //该递归函数结束条件为 每次k的位置变为data的最长时,退出,当然在此之前其实已经完成一个排列
panduan(data);
return;
}
//我们想要的是k位置的数字可以和之后的数字交换位置,进行排列,并且必要的还能恢复到原来的原始状态
for(int i = k;i<data.length;i++) { //i用来代表进行交换位置的下标,所以从k开始
{ //这一块交换也就是k标记下标 和 k后面的数字的一次交换
int temp = data[k];
data[k] = data[i];
data[i] = temp;
}
Sq(data, k+1); //k位置的一次交换过后 ,立马进行递归k+1位置的全排列,保证全排列的进行
{ //k位置的交换 以及 交换过后的k+1位置的全排列结束过后,再将k交换回来,保证原始数据没有发生变换!
int temp = data[k];
data[k] = data[i];
data[i] = temp;
}
//因为两个交换,使得一次循环过后原始数据不变,这个时候进行下一次循环i++,k标记的位置就可以和i代表的k+2的位置的元素,进行交换,全排列,再还原了
}
}
public static void panduan(int[] a) {
if((a[0]+a[1]+a[2]+a[3])==(a[3]+a[4]+a[5]+a[6])&&((a[6]+a[7]+a[8]+a[0])==(a[3]+a[4]+a[5]+a[6]))) {
count++;
}
}
}
生活和学习其实免不了“投机取巧”。学习再厉害,招数 学的再华丽,说不定都会被最普通的方法达到一样的效果。这样的事数不胜数,值得我们反思,有时候去解决一个问题,是否真的需要大费周章,常规思路的解法未尝不是一个好办法。
所以,接下来值得学习的暴力解决法。
方法二:暴力
public class Main {
public static void main(String[] args) {
int a, b, c, d, e, f, g, h, i;
int sum = 0;
for (a = 1; a < 10; a++) {
for (b = 1; b < 10; b++) {
for (c = 1; c < 10; c++) {
for (d = 1; d < 10; d++) {
for (e = 1; e < 10; e++) {
for (f = 1; f < 10; f++) {
for (g = 1; g < 10; g++) {
for (h = 1; h < 10; h++) {
for (i = 1; i < 10; i++) {
if (a + b + d + f == a + c + e + i
&& a + b + d + f == f + g
+ h + i && a != b
&& a != c && a != d
&& a != e && a != f
&& a != g && a != h
&& a != i && b != c
&& b != d && b != e
&& b != f && b != g
&& b != h && b != i
&& c != d && c != e
&& c != f && c != g
&& c != h && c != i
&& d != e && d != f
&& d != g && d != h
&& d != i && e != f
&& e != g && e != h
&& e != i && f != g
&& f != h && f != i
&& g != h && g != i
&& h != i) {
sum++;
}
}
}
}
}
}
}
}
}
}
System.out.println(sum/3/2); //同样除以6
}
}