标签:
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
解决思路:先将所有五个一组的情况遍历,然后用广度优先判断是否连通。
我在选五个一组的时候是用的 for 先选出第几个邮票,然后将其在二维中的位置算出,最后通过广度优先判断二维数组中选中部分连通的位置够不够五个。
#include<iostream>
#include<deque>
using namespace std;
struct point
{
int x;
int y;
};
int main()
{
int sum=0;
int loc[5];
for( loc[0]=1;loc[0]<=8;loc[0]++)
for( loc[1]=loc[0]+1;loc[1]<=9;loc[1]++)
for(loc[2]=loc[1]+1;loc[2]<=10;loc[2]++)
for( loc[3]=loc[2]+1;loc[3]<=11;loc[3]++)
for( loc[4]=loc[3]+1;loc[4]<=12;loc[4]++)
{
int a[4][13];//将选出的一维loc 转到二维数组中 选中置一 为以后判连通做铺垫
memset(a,0,sizeof(a));
int x,y;
for(int i=0;i<5;i++)
{
if(loc[i]%4==0)
{
x=loc[i]/4-1;
y=3;
}
else
{
x=loc[i]/4;
y=loc[i]%4-1;
}
a[x][y]=1;
}
int ans=0;
int book[4][13];//用于将来队列广度遍历时记录当前位置是否用过
memset(book,0,sizeof(book));
point pos;
pos.x=x;
pos.y=y;
book[x][y]=1;
deque<point> ql;
ql.push_back(pos);
ans++;
while(!ql.empty())
{
//计算四个方向时也可以用二维数组储存方向 免得一个一个算
if(a[ql[0].x-1][ql[0].y]&&(ql[0].x-1)>=0&&book[ql[0].x-1][ql[0].y]==0)//up
{
book[ql[0].x-1][ql[0].y]=1;
pos.x=ql[0].x-1;
pos.y=ql[0].y;
ql.push_back(pos);
ans++;
}
if(a[ql[0].x+1][ql[0].y]&&(ql[0].x+1)<=2&&book[ql[0].x+1][ql[0].y]==0)//down
{
book[ql[0].x+1][ql[0].y]=1;
pos.x=ql[0].x+1;
pos.y=ql[0].y;
ql.push_back(pos);
ans++;
}
if(a[ql[0].x][ql[0].y+1]&&(ql[0].y+1)<=3&&book[ql[0].x][ql[0].y+1]==0)//r
{
book[ql[0].x][ql[0].y+1]=1;
pos.x=ql[0].x;
pos.y=ql[0].y+1;
ql.push_back(pos);
ans++;
}
if(a[ql[0].x][ql[0].y-1]&&(ql[0].y-1)>=0&&book[ql[0].x][ql[0].y-1]==0)//l
{
book[ql[0].x][ql[0].y-1]=1;
pos.x=ql[0].x;
pos.y=ql[0].y-1;
ql.push_back(pos);
ans++;
}
ql.pop_front();
}
if(ans==5)
{
sum++;
}
}
cout<<sum;
getchar();
return 0;
}
标签:
原文地址:http://blog.csdn.net/qq_28888837/article/details/51344022