滑动解锁是智能手机一项常用的功能。你需要在3x3的点阵上,从任意一个点开始,反复移动到一个尚未经过的"相邻"的点。这些划过的点所组成的有向折线,如果与预设的折线在图案、方向上都一致,那么手机将解锁。两个点相邻当且仅当以这两个点为端点的线段上不存在尚未经过的点。此外,这条折线还需要至少经过4个点。
为了描述方便,我们给这9个点从上到下、从左到右依次编号1-9。那么1->2->3是不合法的,因为长度不足。1->3->2->4也是合不法的,因为1->3穿过了尚未经过的点2。2->4->1->3->6是合法的,因为1->3时点2已经被划过了。
无意中看到了这道题 而且在知乎回答中 各种语言啊 于是我今天上午无聊时也想做做了 哈哈我可是没看别人的代码 看了正确结果~ 因为感觉搜索搜来搜去 好爽啊 就按照自己想的写了
知乎这道题地址:https://www.zhihu.com/question/24905007
使用DFS(深搜即可) 遍历所有可能的情况 然后筛选不可能的情况
首先使用一个数组 把不可能出现的情况列出
filter[1][3]=filter[3][1]=2;
filter[4][6]=filter[6][4]=5;
filter[7][9]=filter[9][7]=8;
filter[1][7]=filter[7][1]=4;
filter[2][8]=filter[8][2]=5;
filter[3][9]=filter[9][3]=6;
filter[1][9]=filter[9][1]=5;
filter[3][7]=filter[7][3]=5;
然后深搜的同时也进行筛选
void dfs(int count)
{
if(count>=4)
{
result++;
}
for(int i=1;i<=9;i++)
{
if(count>0&&!vis[filter[stamp[count-1]][i]])
continue;
if(!vis[i])
{
vis[i]=1;
stamp[count]=i;
dfs(count+1);
vis[i]=0;
}
}
return ;
}
全部代码:
#include <stdio.h>
#include <string.h>
int filter[10][10];
int stamp[9];
bool vis[10];
int result;
void dfs(int count)
{
if(count>=4)
{
result++;
}
for(int i=1;i<=9;i++)
{
if(count>0&&!vis[filter[stamp[count-1]][i]])
continue;
if(!vis[i])
{
vis[i]=1;
stamp[count]=i;
dfs(count+1);
vis[i]=0;
}
}
return ;
}
int main()
{
memset(filter,0,sizeof(filter));
filter[1][3]=filter[3][1]=2;
filter[4][6]=filter[6][4]=5;
filter[7][9]=filter[9][7]=8;
filter[1][7]=filter[7][1]=4;
filter[2][8]=filter[8][2]=5;
filter[3][9]=filter[9][3]=6;
filter[1][9]=filter[9][1]=5;
filter[3][7]=filter[7][3]=5;
result=0;
vis[0]=true;
dfs(0);
printf("%d\n",result);
}
结果: