问题描述:
在 3*3 的点阵上绘制手势解锁图案
要求:
1. 所绘制图案至少经过四个点;
2. 不能重复经过同一个点;
3. 路径上的中间点不能跳过(如从1到3一定会经过2);
4. 如果中间的点是之前已经用过的,那么这个点就可以被跳过(如213,因为2已经被用过,1就可以越过2与3连接,132是不允许的)。
经计算,总次数为 389112
// 手机图案解锁问题
// 至少四点以上才成立
// 使用dfs深度搜索方法
#include<iostream>
using namespace std;
int sum = 0; //开锁总次数
int interval[10][10] = { 0 }; //判断节点间的间隔点(即必穿过点)
int used[10] = { 0 }; //记录使用点的情况(1--9)
//used[i]=1 表示已使用, used[i]=0 表示未使用
int sequence[10] = { 0 }; //记录使用点的顺序
void dfs(int Count)
{
if (Count >= 4)
sum++;
if (Count >= 9) //Count大于等于9结束
return;
for (int i = 1; i <= 9; i++)
{
//当节点已使用或间隔点未使用时直接进入下一次循环
if (used[i] == 1 || (Count > 0 && used[interval[sequence[Count - 1]][i]] == 0))
continue;
if (used[i] == 0)
{
used[i] = 1;
sequence[Count] = i;
dfs(Count + 1);
used[i] = 0;
sequence[Count] = 0;
}
}
}
int main()
{
//各点间的间隔点
interval[1][3] = interval[3][1] = 2;
interval[1][7] = interval[7][1] = 4;
interval[1][9] = interval[9][1] = 5;
interval[2][8] = interval[8][2] = 5;
interval[3][7] = interval[7][3] = 5;
interval[3][9] = interval[9][3] = 6;
interval[4][6] = interval[6][4] = 5;
interval[7][9] = interval[9][7] = 8;
used[0] = 1; //将 首位 置1用于判断
dfs(0); //设置开始时Count为0,进行搜索
cout << sum;
return 0;
}