LintCode:Android Unlock Patterns

Given an Android 3x3 key lock screen and two integers mand n, where 1 ≤ m ≤ n ≤ 9, count the total number of unlock patterns of the Android lock screen, which consist of minimum of m keys and maximum n keys.

Rules for a valid pattern:
1. Each pattern must connect at least m keys and at most nkeys.
2. All the keys must be distinct.
3. If the line connecting two consecutive keys in the pattern passes through any other keys, the other keys must have previously selected in the pattern. No jumps through non selected key is allowed.
4. The order of keys used matters.
android unlock
Explanation:

| 1 | 2 | 3 |
| 4 | 5 | 6 |
| 7 | 8 | 9 |

Invalid move: 4 - 1 - 3 - 6
Line 1 - 3 passes through key 2 which had not been selected in the pattern.

Invalid move: 4 - 1 - 9 - 2
Line 1 - 9 passes through key 5 which had not been selected in the pattern.

Valid move: 2 - 4 - 1 - 3 - 6
Line 1 - 3 is valid because it passes through key 2, which had been selected in the pattern

Valid move: 6 - 5 - 4 - 1 - 9 - 2
Line 1 - 9 is valid because it passes through key 5, which had been selected in the pattern.

 

思路:DFS,1,3,7,9四点对称,2,4,6,8四点对称,还剩一个5,故只需计算1,2,5三个点。对于任意两个点的坐标(x1,y1),(x2,y2),如果((x1+x2)%2==0 && (y1+y2)%2==0),说明两点连线之间存在一个中点((x1+x2)/2, (y1+y2)/2)。如果这个中点被访问过,则这两点是可以连通的;如果中点没有被访问过,则两点不能连通。如果两点间不存在中点,则两点也是可以连通的。

 1 class Solution {
 2 public:
 3     /**
 4      * @param m: an integer
 5      * @param n: an integer
 6      * @return: the total number of unlock patterns of the Android lock screen
 7      */
 8     bool isCanGo(int curi, int curj, int i, int j, vector<vector<bool> > &visited)
 9     {
10         int sum1=curi+curj;
11         int sum2=i+j;
12         if(sum1-sum2==1 || sum2-sum1==1)return true;
13         if((curi+i)%2==0 && (curj+j)%2==0)return visited[(curi+i)/2][(curj+j)/2];
14         return true;
15     }
16     int DFS(int m, int n, int curi, int curj, int len, vector<vector<bool> > &visited)
17     {
18         if(len>n)return 0;
19         int sum=0;
20         if(len>=m && len<=n)++sum;
21         visited[curi][curj]=true;
22         for(int i=0; i<3; ++i)
23         {
24             for(int j=0; j<3; ++j)
25             {
26                 if(curi==i && curj==j)continue;
27                 if(visited[i][j])continue;
28                 if(isCanGo(curi, curj, i, j, visited))sum=sum+DFS(m, n, i, j, len+1, visited);
29             }
30         }
31         visited[curi][curj]=false;
32         return sum;
33     }
34     int numberOfPatterns(int m, int n) {
35         if(m<=0 || n<=0 || m>n)return -1;
36         vector<vector<bool> > visited(3, vector<bool>(3, false));
37         return DFS(m, n, 0, 0, 1, visited)*4+DFS(m, n, 0, 1, 1, visited)*4+DFS(m, n, 1, 1, 1, visited);
38     }
39 };

 

 

 

 

posted @ 2018-03-27 10:41  jeysin  阅读(573)  评论(0编辑  收藏  举报