從網上看到的別人的代碼,稍微修改了一下,先看一下原博主怎麼寫的吧
**
原博主問題描述與代碼
**
下面的代碼 我只是加了一些註釋,少於了兩個把郵票塊數值轉換爲行列座標的數組,因爲水平不夠,那兩個數組的使用讓我理解起來很困難,所以我就去掉了
# 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;
}