从网上看到的别人的代码,稍微修改了一下,先看一下原博主怎么写的吧
**
原博主问题描述与代码
**
下面的代码 我只是加了一些注释,少于了两个把邮票块数值转换为行列坐标的数组,因为水平不够,那两个数组的使用让我理解起来很困难,所以我就去掉了
# include <iostream>
# include <cstring>
using namespace std;
int result = 0;
int mtx[10][10] = {0}; //保存邮票的图 值0代表当前位置未被选中,值为1代表当前位置被选中
int c[5]={0}; // 记录当前选择的五个邮票块的数字
int sum(int x,int y)
{
if(mtx[x][y] == 0) //如果没选择就直接返回了 不用再判断周围的有没有选中 因为选中的必须要是相连的
{
return 0;
}
else
{
mtx[x][y] = 0; //选过的就把值赋值为0,避免无限循环
return 1+ sum(x-1,y) + sum(x+1,y) + sum(x,y-1) + sum(x,y+1); //查找一下上下左右有没有选中的,因为这些位置的都是相连的
}
}
void dfs(int last,int i) //选择5个邮票块的情况 这里的5个邮票快都是递增的 所以不存在重复的情况
{
if(i<5) //这个if循环快可以是一个排列模板
{
while(++last<=12) //++last 首先视为了配合主函数中的第一次传入的值是0,0 让第一次循环选中第一个邮票块,
{ //++也是为了让邮票块的选择都是递增的,不会出现重复的情况,
c[i] = last;
dfs(last,i+1);
}
}
else //已经选择了5个
{
memset(mtx,0,sizeof(mtx));//初始化
int x,y;
//给mtx的对应位置复制
for(int j =0;j<5;j++)
{
//根据选中的邮票块数值 转换为对应的行列位置
x = c[j]/4; //x代表第几行
y = c[j]%4-1; //y代表第几列
if(c[j]%4 == 0 )
{
x = x-1;
y = 3;
}
mtx[x][y] = 1;
}
if(sum(x,y) == 5) //都过坐标方位mtx数组 判断时否选择了相邻的5个邮票块
{
result ++;
}
}
}
int main()
{
dfs(0,0); //从0,0开始
printf("%d\n",result);
return 0;
}