刷题感悟,笔记整理
标题:
纸牌三角形
A,2,3,4,5,6,7,8,9 共9张纸牌排成一个正三角形(A按1计算)。要求每个边的和相等。
下图就是一种排法(如有对齐问题,参看p1.png)。
这样的排法可能会有很多。
如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?
请你计算并提交该数字。
注意:需要提交的是一个整数,不要提交任何多余内容。
分析
这道题属常规填空题,无时间限制可以用暴力法暴力,对于新手比较友好
但也可以用全排列或者bfs来求解。
因为镜像要处以2,旋转要处以3,所以最后输出要处以6
法一:全排列
package 真题2017;
public class zhipaisanjiaoxing2 {//全排列法
public static int counts=0;
public static void swap(int[]a,int i,int j) {
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
public static void quanpailie(int[]a,int start) {
if(start==a.length) {//当数字齐全时,开始判定
int A=a[0]+a[1]+a[2]+a[3];
int B=a[3]+a[4]+a[5]+a[6];
int C=a[6]+a[7]+a[8]+a[0];
if(A==B&&A==C) {
counts++;
}
}else {
for(int i=start;i<a.length;i++) {
swap(a,i,start);//回溯
quanpailie(a,start+1);
swap(a,i,start);
}
}
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
int[]a= {1,2,3,4,5,6,7,8,9};
quanpailie(a,0);//扔进去全排列
System.out.println(counts/6);//扣除镜像和旋转的要除以6
}
}
法二:dfs
package 真题2018;
public class zhipaisanjiaoxing2_2 {//dfs
public static int n=9;//定义全局变量,方便少写参
public static int[]a=new int[n];
public static int[]b=new int[n];//判定是否正在执行中
public static int counts=0;
public static void dfs(int start) {
if(start==n) {//末端判定条件
int A=a[0]+a[1]+a[2]+a[3];
int B=a[3]+a[4]+a[5]+a[6];
int C=a[6]+a[7]+a[8]+a[0];
if(A==B&&A==C) {
counts++;
}
}
else {
for(int i=0;i<9;i++) {
if(b[i]==0) {//判定是否相同下执行过
a[start]=i+1;//没有则当天元素等于i+1,因为数组下标由0开始;
b[i]=1;//回溯的原理
dfs(start+1);
b[i]=0;//回溯
}
}
}
}
public static void main(String[] args) {
dfs(0);
System.out.println(counts/6);
}
}
个人感觉两种方法的不同点在于:
全排列时交换数组元素的排列位置,而dfs是即时生成自动填充。
以上均参考其他博客的解法