数字键盘锁 dfs

来源:互联网 发布:java 调用 maven 编辑:程序博客网 时间:2024/05/21 08:16
总时间限制:
1000ms
内存限制:
65536kB
描述

几乎所有的安卓智能手机都有九宫格键盘锁,如下图1所示。从随机的一个点开始,按一定顺序依次向不同的点划动,可以形成一条路径,以达到加锁和解锁手机的目的。现在把键盘锁抽象成下图2所示3*3的矩阵,把每个点用数字来表示。


图1 键盘锁

图2 编号示意

一个数字键盘锁的合法性描述如下:

1.一个合法的手势图案,由一串数字组成,这串数字只记录每个点第一次被触碰到时的顺序。我们把这串数字称为手势数字,把触碰过的点称为激活点

2.在手势数字中,两个相邻的数字必须可以直接相连,或者经过激活点相连;否则,这个手势数字就是不合法的。

现在给出九宫格键盘锁要使用到的N个数字点,要求每个数字点都要被使用到,求有多少种合法的手势数字


输入
第一行一个正整数K(1≤K≤10)表示之后有K组数据。
之后每组数据占2行,第1行一个正整数N(3≤N≤9),第2行N个互不相同的正整数Num1,Num2,...NumN(1≤Num≤9)表示将在键盘锁中使用到的N个数字。
输出
对应每组输入数据,输出一个正整数,代表有多少合法的手势数字。
样例输入
231 2 441 2 3 9
样例输出
62
提示
对于第二个样例,只有9→2→1→3和9→2→3→1两组合法的手势。
#include <cstdio>#define my_abs(x) (((x)>=0)?(x):(-(x)))bool num[10];bool used[10];bool REACH( int a, int b ){if ( (a==0) || (b==0) )return true;if ( (my_abs(((a-1)/3)-((b-1)/3))==1) || (my_abs(((a-1)%3)-((b-1)%3))==1) )return true;return ( used[(a+b)>>1] );}int DFS( int depth, int u ){if ( depth <= 0 )return 1;int ret = 0;for ( int v=1; v<=9; v++ ){if ( num[v] && REACH(u,v) ){num[v] = 0;used[v] = 1;ret += DFS( depth-1, v );num[v] = 1;used[v] = 0;}}return ret;}int main(){int t, n, tmp;//freopen( "in2.in", "r", stdin );//freopen( "YYC2.out", "w", stdout );scanf( "%d", &t );for ( int cas=1; cas<=t; cas++ ){for ( int i=1; i<=9; i++ ){num[i] = 0;used[i] = 0;}scanf( "%d", &n );for ( int i=0; i<n; i++ ){scanf( "%d", &tmp );num[tmp] = 1;}//printf( "case %d: %d\n", cas, DFS( n, 0 ) );printf( "%d\n", DFS( n, 0 ) );}return 0;}

0 0
原创粉丝点击