【蓝桥杯】2017省赛JAVA_B 纸牌三角形 全排列

题目

纸牌三角形

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判断

【蓝桥杯】2017省赛JAVA_B 纸牌三角形 全排列_第1张图片

转自: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

 

你可能感兴趣的:(LanQiaoBei)