pattern lock
前几天和一朋友聊到手机解锁, 朋友问我有没有想过手机pattern lock有多少种组合方式. 其实这个问题早就想过了, 以前感觉会有很多种特殊情况, 用程序解还不如用排列组合来得快
后来讨论了下, 就决定把问题简化: 只考虑4个点或4个点以上的情形, 并且包含下图这种路径的不算有效的组合方式

用回溯写了个解
#define N 4
typedef struct
{
char *pa;
char *pn;
} point_info;
int x[10] = {0};
point_info points[10];
void init_points()
{
points[0].pa = "x1x2x3x4x5x6x7x8x9";
points[0].pn = "";
points[1].pa = "x2x4x5x6x8";
points[1].pn = "x3x7x9";
points[2].pa = "x1x3x4x5x6x7x9";
points[2].pn = "x8";
points[3].pa = "x2x4x5x6x8";
points[3].pn = "x1x7x9";
points[4].pa = "x1x3x5x6x7x8x9";
points[4].pn = "x6";
points[5].pa = "x1x2x3x4x6x7x8x9";
points[5].pn = "";
points[6].pa = "x1x2x3x5x7x8x9";
points[6].pn = "x4";
points[7].pa = "x2x4x5x6x8";
points[7].pn = "x1x3x9";
points[8].pa = "x1x3x4x5x6x7x9";
points[8].pn = "x2";
points[9].pa = "x2x4x5x6x8";
points[9].pn = "x1x3x7";
}
int last_ele(point_info *p)
{
char *str = p->pa;
return *(str + strlen(str) - 1);
}
int last_ele(point_info *p)
{
char *str = p->pa;
return *(str + strlen(str) - 1);
}
int next_ele(point_info *p, int e)
{
char *str;
int i;
str = p->pa;
if(0 == e)
return *str;
for(i = strlen(str) - 1; i > 0; --i, ++str)
if(*str == e)
return *(str + 1);
return *str + 1;
}
int correct(int p)
{
int i;
for(i = p - 1; i > 0; --i)
if(*(x + i) == *(x + p))
return 0;
return 1;
}
void print_ans(int leng)
{
int i = 1;
for (; i <= leng; ++i)
printf("%d", *(x + i));
printf("n");
}
int back_track(int leng)
{
int count = 0, p = 1;
while (p > 0)
{
point_info *pre = points + x[p - 1];
x[p] = next_ele(pre, x[p]);
while(!correct(p) && x[p] <= last_ele(pre))
x[p] = next_ele(pre, x[p]);
if(x[p] > last_ele(pre))
{
x[p] = 0;
--p;
}
else
{
if(p != leng)
++p;
else
++count;
}
}
return count;
}
int main(int argc, char **argv)
{
int i = 4, count = 0, tmp;
init_points();
for(; i < 10; ++i)
{
tmp = back_track(i);
printf("%dn", tmp);
count += tmp;
}
printf("%dn", count);
return 0;
}
写得有点quick dirty, 得出的答案是140045, 不知道对不对
先放这里, 抽空再研究研究