图片来自:https://www.cnblogs.com/sunriseblogs/p/9873013.html
排列代码
import java.math.BigInteger;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
public class Main61 {
public static int []a;
public static int len;
public static int count=0;
public static void fun(int n) {
if (n==len) {
System.out.println(Arrays.toString(a));
}else {
for (int i = n; i <len; i++) {
swap(i,n);
fun(n+1);
swap(n, i);
}
}
}
//交换下标x与y的值
public static void swap(int x,int y) {
int t=a[x];
a[x]=a[y];
a[y]=t;
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();//输入数组长度
len=n;
a=new int[n];
for (int i = 0; i <n; i++) {
a[i]=sc.nextInt();
}
fun(0);
}
}
例题如下
A,2,3,4,5,6,7,8,9 共9张纸牌排成一个正三角形(A按1计算)。要求每个边的和相等。
下图就是一种排法(如有对齐问题,参看p1.png)。
A
9 6
4 8
3 7 5 2
这样的排法可能会有很多。
如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?
请你计算并提交该数字。
注意:需要提交的是一个整数,不要提交任何多余内容。
思路:把三角形的边当做一个长度为九的数组,全排列判断
a[0]+a[1]+a[2]+a[3];
a[3]+a[4]+a[5]+a[6];
a[6]+a[7]+a[8]+a[0];
是否相等
需要注意,每一种三边相等的组合都会有三种旋转的角度存在和三种旋转角度的镜像存在,所以六种中只取一种。结果除以6
import java.util.Arrays;
import java.util.Scanner;
public class Main61 {
public static int []a={1,2,3,4,5,6,7,8,9};
public static int count=0;
public static void fun(int n) {
if (n==9) {
//System.out.println(Arrays.toString(a));
int s1=a[0]+a[1]+a[2]+a[3];
int s2=a[3]+a[4]+a[5]+a[6];
int s3=a[6]+a[7]+a[8]+a[0];
if (s1==s2&&s2==s3) {
count++;
}
}else {
for (int i = n; i <9; i++) {
swap(i,n);
fun(n+1);
swap(n, i);
}
}
}
//交换下标x与y的值
public static void swap(int x,int y) {
int t=a[x];
a[x]=a[y];
a[y]=t;
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
fun(0);
System.out.println(count/6);
}
}
2020年3月12日11:16:47 以下为后期补充
用stack实现全排列,代码更为简洁,statck把两个数的交换swap(a,b)换成了添加一个数据,和删除这个数据,逻辑上还是相同的。
全排列一般有三种:
1. 全部排列 可以重复使用数字
2. 全部排列 不可以重复使用数字
3. 部分排列 选取m个数字有多少种排列
import java.util.Stack;
public class Main03 {
//递归 回溯 Stack实现全排列(可以重复使用数字)
public static Stack<Integer> stack=new Stack<Integer>();
/**
* @param shu 待选择的数组
* @param targ 要选择多少个次
* @param cur 当前选择的是第几次
*/
public static void main(String[] args) {
int shu[]={1,2,3};
f(shu,3,0);;
}
public static void f(int shu[],int targ,int cur) {
if (cur==targ) {
System.out.println(stack);
return ;
}
for (int i = 0; i < shu.length; i++) {
stack.push(shu[i]);//添加数据
f(shu, targ, cur+1);
stack.pop();//删除后进数据
}
}
}
import java.util.Stack;
public class Main03 {
//递归 回溯 实现全排列(不可以重复使用数字)
public static Stack<Integer> stack=new Stack<Integer>();
/**
* @param shu 待选择的数组
* @param targ 要选择多少个次
* @param cur 当前选择的是第几次
*/
public static void main(String[] args) {
int shu[]={1,2,3};
f(shu,3,0);;
}
public static void f(int shu[],int targ,int cur) {
if (cur==targ) {
System.out.println(stack);
return ;
}
for (int i = 0; i < shu.length; i++) {
if (!stack.contains(shu[i])) {
stack.push(shu[i]);//添加数据
f(shu, targ, cur+1);
stack.pop();//删除后进数据
}
}
}
}
import java.util.Stack;
public class Main03 {
//递归 回溯 实现全排列(选择targ个元素的排列方式)
public static Stack<Integer> stack=new Stack<Integer>();
/**
* @param shu 待选择的数组
* @param targ 要选多少个元素
* @param has 当前有多少个元素
* @param cur 当前选到的下标
*/
public static void main(String[] args) {
int shu[]={1,2,3,4};
f(shu,3,0,0);;
}
public static void f(int shu[],int targ,int has,int cur) {
if (has==targ) {
System.out.println(stack);
return ;
}
for (int i = cur; i < shu.length; i++) {
if (!stack.contains(shu[i])) {
stack.push(shu[i]);//添加数据
f(shu, targ,has+1,i);
stack.pop();//删除后进数据
}
}
}
}