原
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
滑动解锁是智能手机一项常用的功能。你需要在3x3的点阵上,从任意一个点开始,反复移动到一个尚未经过的"相邻"的点。这些划过的点所组成的有向折线,如果与预设的折线在图案、方向上都一致,那么手机将解锁。两个点相邻当且仅当以这两个点为端点的线段上不存在尚未经过的点。此外,这条折线还需要至少经过4个点。
为了描述方便,我们给这9个点从上到下、从左到右依次编号1-9。那么1->2->3是不合法的,因为长度不足。1->3->2->4也是合不法的,因为1->3穿过了尚未经过的点2。2->4->1->3->6是合法的,因为1->3时点2已经被划过了。
无意中看到了这道题 而且在知乎回答中 各种语言啊 于是我今天上午无聊时也想做做了 哈哈
我可是没看别人的代码 看了正确结果~ 因为感觉搜索搜来搜去 好爽啊 就按照自己想的写了
使用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;i0&&!vis[filter[stamp[count-1]][i]])	continue;	if(!vis[i])	{	vis[i]=1;	stamp[count]=i;	dfs(count+1);	vis[i]=0;	}	}	return ; }
全部代码:#include#includeint filter[10][10]; int stamp[9]; bool vis[10]; int result; void dfs(int count) {	if(count>=4)	{	result++;	}	for(int i=1;i0&&!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); }
结果:
需要满足的要求有:至少经过四个点;不能重复经过同一个点;路径上的中间点不能跳过(如从1到3一定会经过2);如果中间的点是之前已经用过的,那么这个点就可以被跳过(如213,因为2已经被用过,1就可以越过...