纸牌三角形
A,2,3,4,5,6,7,8,9 共9张纸牌排成一个正三角形(A按1计算)。要求每个边的和相等。
下图就是一种排法(如有对齐问题,参看p1.png)。
A
9 6
4 8
3 7 5 2
这样的排法可能会有很多。
如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?
请你计算并提交该数字。
注意:需要提交的是一个整数,不要提交任何多余内容。
由于本题是填空题,可以使用暴力破解的办法——9个for和if判断
转自:https://blog.csdn.net/xiaodingqq/article/details/79487838
但若考虑到时间复杂度,这其实可以简化为全排列问题。
而本文使用的是递归全排列。
全排列:从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。
公式:全排列数f(n)=n!(定义0!=1)
以递归的方式全排列:n为任意数,在此设n=4,那么共有 a b c d 4个位置(不是具体数字)。
递归的方式即可理解为:
在a位确定后,剩下bcd位的全排列。
剩下bcd位的全排列 变为 在b位确定后,剩下cd位的全排列。
剩下cd位的全排列 变为 在c位确定后,剩下d位的全排列 。
d位的全排列为自身,此时已经把一个排列确定,输出。
实现全排列的方法为交换,本位与本位以后的各位交换。如:a位分别与 a(相当于不交换)、b、c、d位上的数字交换。
每次交换 并进一步处理完后,需要将交换变回原样,以便于下一次处理。
我们将 a b c 位初始位置设为 1 2 3 开始。
length=3,所以for循环3次。
1与1交换,这时a位确定完毕,递归进入 2 3的全排列。
length=2,所以for循环2次。
2与2交换,这时b位确定完毕,递归进入 3的全排列。
length=1,所以for循环1次。
c位上的3与自身交换还是自身,且后面没有可以交换的数,在此做一个判断,输出 1 2 3.
这时退回了 2 3 的全排列,上次的2与2交换for结束,2与2再次交换(变回交换前的状态)
因为for2次,此次b与 c 交换,此时b位为3确定,进入 2 的全排列。
length=1,for循环一次。
c位上的2与自身交换还是自身,且后面没有可以交换的数,在此做一个判断,输出 1 3 2
for完成,此时退回 2 3 全排列,首先恢复 b c位,变为 1 2 3,for2次以结束。
退回 1 2 3全排列,首先 a 位 和a位交换,变回原状态
因为for3次,此次a位和b位交换变为2 1 3,此时 a位确定,递归进入 1 3的全排列
length=2,for2次
b位与b位交换,b位确定为1,进入3的全排列
length=1,for1次
c位上的3与自身交换还是自身,且后面没有可以交换的数,在此做一个判断,输出 2 1 3
for完成,此时退回 1 3 的全排列。b位与b位交换,变回原状态。
因为for2次,此次b位和c位交换,b位确定为3,进入1的全排列。
length=1,for1次。
c位上的3与自身交换还是自身,且后面没有可以交换的数,在此做一个判断,输出 2 3 1
for完成,b位和c位交换,退回原状态——2 1 3
for2次完成,a位和b位交换,退回原状态——1 2 3
因为for3次,此次a位和c位交换,此时a位确定为3,递归进入 2 1 的全排列。
length=2,for2次
b位与b位交换,此时b位确定为2,进入 1 的全排列。
length=1,for1次
c位上的3与自身交换还是自身,且后面没有可以交换的数,在此做一个判断,输出3 2 1
for完成,退回 2 1 的全排列,b位与b位交换,变回原状态。
因为for2次,此次b位和c位交换,b位确定为1,递归进入2的全排列。
length=1,for1次。
c位上的3与自身交换还是自身,且后面没有可以交换的数,在此做一个判断,输出3 1 2
for完成,退回b c全排列,b位c位互换,变回原状态
for2次完成,退回a b c全排列,a c 互换,变回原状态
for3次完成,结束.
(以上描述过程可能有疏漏,但大体没问题)
输出顺序为:
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
3 1 2
package exam17;
import java.util.Scanner;
public class no3_mine {
public static void main(String[] args) {
//输入
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
char[] in = input.toCharArray();
//开始进入递归
sq(in,0);
}
private static void sq(char[] in, int k) {
// TODO Auto-generated method stub
//如果递归到最后一个数,直接输出即可
if(k==in.length-1) {
for(char c :in) {
System.out.print(c);
}
System.out.println();
}else {
//不是最后一个数,仍存在交换可能
//k是要确定的位置,k要与本身和之后的所有位交换
for(int i=k;i