蓝桥杯 16省赛 B7 剪邮票(阅读理解)
剪邮票
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
图1
图2
图3
思路:
先dfs 遍历不同位置的邮票组合
然后bfs 判断具体组合中判断是否孤立的邮票
(OS:这题把我折磨惨了,题目的意思其实是有5个方块的组合,不是说裁剪"边"的方式 …)
public class 剪邮票_bfs_dfs_7 {
static Queue<Integer> q =new LinkedList<Integer>(); //不多说了,bfs就两个队列倒腾就可以实现了
static Queue<Integer> tmp =new LinkedList<Integer>();
static int[] a =new int[5];
static int[] b = {-1 ,1 ,-4 ,4};
static int ans;
public static void main(String[] args) {
dfs(0 ,0);
System.out.println(ans);
}
private static void dfs(int val ,int lev) {
if(lev ==5) {
if(jud()) ans ++;
return ;
}
for(int i =val +1 ;i <13 ;i ++) {
a[lev] =i;
dfs(i ,lev +1);
}
}
private static boolean jud() { //先便利后校验
for(int i :a) q.add(i);
int i =0 ,index =0;
tmp.add(q.poll());
while(!tmp.isEmpty()) {
i =tmp.poll();
for(int pos =0 ;pos <4 ;pos ++) {
index =i +b[pos];
if(index <1 ||index >12) continue;
if(pos ==0 &&index %4 ==0) continue;
if(pos ==1 &&i %4 ==0) continue;
if(q.contains(index)) {
tmp.add(index);
q.remove(index);
if(q.isEmpty()) {
tmp.clear();
return true;
}
}
}
}
q.clear(); //这部还是别偷懒了,翻车就不好了
return false;
}
}