剪邮票

114 阅读1分钟

如:
image.png
有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,

image.pngimage.png
粉红色所示部分就是合格的剪取。

请你计算,一共有多少种不同的剪取方法。

请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

分析:

暴力枚举5个位置, 对这五个位置所组成的状态进行DFS, 如果五个位置是连接的,则一次深搜即可扫描五个位置 否则即为不连接
116

代码


import java.util.Collections;
import java.util.HashSet;

public class 剪邮票 {
	public static int count=0;
	public static int arr[][]=new int [3][4];
	public static void dfs(int x,int y,int step){
		arr[x][y]=0;
		if(step==5){
			return;
		}
		if(x-1>=0&&x-1<3&&arr[x-1][y]==1){
			dfs(x-1,y,step+1);
		}
		if(x+1>=0&&x+1<3&&arr[x+1][y]==1){
			dfs(x+1,y,step+1);
		}
		if(y-1>=0&&y-1<4&&arr[x][y-1]==1){
			dfs(x,y-1,step+1);
		}
		if(y+1>=0&&y+1<4&&arr[x][y+1]==1){
			dfs(x,y+1,step+1);
		}
	}
	public static void check(HashSet<Integer> set){
		
		int i=-1,j=-1;
		for(int x:set){
			arr[x/4][x%4]=1;
			i=x/4;
			j=x%4;
		}
		dfs(i,j,1);
		boolean flag=true;
		for(i=0;i<3;i++){
			for(j=0;j<4;j++){
				if(arr[i][j]==1){
					flag=false;
					arr[i][j]=0;
				}
			}
		}
		if(flag){
			count++;
		}
	}
	public static void insert(HashSet set,int k){
		if(set.size()==5){
			check(set);
		}
		else{
			for(int i=k;i<12;i++){
				set.add(i);
				insert(set,i+1);
				set.remove(i);
			}
		}
	}
	public static void main(String[] args) {
		HashSet<Integer> set=new HashSet<Integer>();
		insert(set,0);
		System.out.println(count);
	}

}