手势密码

很多手机或平板电脑软件都可以设置手势密码,在设置了手势密码后,进入程序时,首先要输入手势密码。

手势密码最少选择4个点,最多选择9个点,理论上的密码组合总共有985824种,扣除掉其中不可能完成的组合(如一些点不允许绕过),最终的可能性是389112种。可见,手势密码加强了软件访问的安全性。

下面介绍一下手势密码的规则(如果你熟悉手势密码的规则,可略过):

1)  从某一个点出发,不间断地画线连接4-9个点,则从起点至终点构成的有序轨迹便构成一个有效的手势密码。

2)  在水平、垂直及对角方向上的3个点(假设依次为A点、B点、C点),在B点是未选点的情况下,A点是绕不过B点直接与C点相连的,如点1和点3直线连接绕不过点2。同样道理,点1和点9直线连接绕不过点5,等等。如图3所示,如果起点是1点,则手势密码必为1->2->3->6->5->4->7->8->9,而不可能是1->3->6->4->7->9。

3)  在连线不间断延展的过程中,只要还有未选的新点,就可以画线连接到该新点,而不管是否有重叠或是交叉,即经过已选点或已连线均可。例如,2->3->1->5或1->5->2->4都是允许的。

4)  在连线不间断延展的过程中,中间点是不允许经过2次的(除非是规则3说明的情况),终点虽然可以再连接到已选点,但却是无效的。例如,以1点为起点,则图4所示的手势密码跟图3所示的手势密码是一样的。

   

  

对于没研究过手势密码的同学,虽然我上面啰嗦了这么多,估计还是有疑惑的地方,干脆简单点说吧!

实际上,n个点能够构成的手势密码种数=n个点的排列总数-不可能完成的哪些排列数。

输入

有多行测试数据

每行包括2个数据:min和max,表示最少选择min个点,最多选择max个点。取值范围为4<=min<=max<=9。输入时min和max用空格隔开。

输出

与每行输入相对应,输出可以构成的手势密码总数。

样例输入

4 44 9

样例输出

1624
389112

#include 
#include 
#include 
#include 
#include  b
using namespace std;
int max1;
int min1;
int sum=0;
int a[20]={0};
int b[20][20]={0};
int handpass(int ,int ,int);
int handpass(int i,int n)
{
    int j;
    if(n>=min1&&n<=max1)
        sum++;
    for(j=1;j<=9;j++)
    {
        if(a[j]==0)
        {
            if(b[i][j]!=0&&a[b[i][j]]==0)
                continue;
            else
            {
                a[j]=1;
                handpass(j,n+1);
                a[j]=0;
            }
        }
    }
    return 0;
}
int main()
{
    b[1][3]=b[3][1]=2;
    b[1][7]=b[7][1]=4;
    b[1][9]=b[9][1]=5;
    b[3][9]=b[9][3]=6;
    b[7][9]=b[9][7]=8;
    b[8][2]=b[2][8]=5;
    b[3][7]=b[7][3]=5;
    b[4][6]=b[6][4]=5;
    while(scanf("%d %d",&min1,&max1)!=EOF)
    {
        sum=0;
        handpass(0,0);
        printf("%d\n",sum);
    }
    return 0;
}

你可能感兴趣的:(OJ)