剪邮票
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
解析:因为只有十二个元素,所以可以暴力循环,嵌套五层for循环找到5个元素 ,将这些点转化为图3行4列,
行数等于i/4 列数等于i%4 ,将其他点置为不可访问,将这五个元素置为可访问,于是bfs,如果五个元素全访问到,则这种方案可行,ans++
话不多说,代码如下:
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
public class L2016剪邮票 {
static boolean vis[][]=new boolean[3][4];
static int mp[][]=new int[3][4];
static int dx[]={-1,0,1,0};
static int dy[]={0,-1,0,1};
static class d{//点
int x;
int y;
public d(int x,int y)
{
this.x=x;
this.y=y;
}
}
static Queue<d> q=new LinkedList<d>();
static void init()
{
for(int i=0;i<3;i++)
{
Arrays.fill(vis[i], false);
Arrays.fill(mp[i],-1);//障碍
}
}
static boolean Check(int x,int y)
{
if(x>=0&&y>=0&&x<3&&y<4&&mp[x][y]!=-1)//先判断范围,再判断是否为障碍,从而达到防止
//数组越界的效果
return true;
return false;
}
static void bfs(int x,int y)
{
d cor=new d(x,y);
q.add(cor);
while(!q.isEmpty())
{
d now=q.poll();
for(int i=0;i<4;i++)
{
int xx=now.x+dx[i];
int yy=now.y+dy[i];
if(Check(xx,yy)&&!vis[xx][yy])
{
vis[xx][yy]=true;
d next=new d(xx,yy);
q.add(next);
}
}
}
return ;
}
public static void main(String[] args)
{
int ans=0;
for(int i=0;i<12;i++)
{
for(int j=i+1;j<12;j++)
{
for(int k=j+1;k<12;k++)
{
for(int l=k+1;l<12;l++)
{
for(int m=l+1;m<12;m++)
{
init();
mp[i/4][i%4]=1;//转换
mp[j/4][j%4]=1;
mp[k/4][k%4]=1;
mp[l/4][l%4]=1;
mp[m/4][m%4]=1;
vis[i/4][i%4]=true;
bfs(i/4,i%4);
if(vis[i/4][i%4]==true
&&vis[j/4][j%4]==true
&&vis[k/4][k%4]==true
&&vis[l/4][l%4]==true
&&vis[m/4][m%4]==true)
{
ans++;
}
}
}
}
}
}
System.out.println(ans);
}
}
得到答案:
116
感受:
蓝桥杯填空题基本都可以暴力呀!!!