Pattern lock security is generally used in Android handsets instead of a password. The pattern lock can be set by joining points on a 3 × 3 matrix in a chosen order. The points of the matrix are registered in a numbered order starting with 1 in the upper left corner and ending with 9 in the bottom right corner.
A valid pattern has the following properties:
Now you are given n active points, you need to find the number of valid pattern locks formed from those active points.
There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:
The first line contains an integer n (3 ≤ n ≤ 9), indicating the number of active points. The second line contains n distinct integers a1, a2, … an (1 ≤ ai ≤ 9) which denotes the identifier of the active points.
For each test case, print a line containing an integer m, indicating the number of valid pattern lock.
In the next m lines, each contains n integers, indicating an valid pattern lock sequence. The m sequences should be listed in lexicographical order.
1
3
1 2 3
4
1 2 3
2 1 3
2 3 1
3 2 1
题意:手机图案解锁,给定n个数字,求可以得到的图案有多少种。其中有一些数字需要借助别的数字才能到达。
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<algorithm> using namespace std; int vis[300],a[11],mp[11][11]; int ans[400000][11],f[11]; int n,len; void init() { mp[1][3] = 2; mp[3][1] = 2; mp[1][7] = 4; mp[7][1] = 4; mp[1][9] = 5; mp[9][1] = 5; mp[2][8] = 5; mp[8][2] = 5; mp[3][7] = 5; mp[7][3] = 5; mp[3][9] = 6; mp[9][3] = 6; mp[4][6] = 5; mp[6][4] = 5; mp[7][9] = 8; mp[9][7] = 8; } void print() { for (int i = 0; i < n; i++) { ans[len][i] = f[i]; } len++; } void dfs(int cur,int x) { if (x == n) { print(); return; } for (int i = 0; i <n; i++) { if (vis[a[i]] == 0 && (mp[a[i]][cur] == 0 || vis[mp[a[i]][cur]] == 1))//判断方式跟枚举一样 { vis[a[i]] = 1; f[x] = a[i]; dfs(a[i], x + 1);//a[i]作为cur传递,相当于两个两个比较 vis[a[i]] = 0;//有多种,递归不成功改回来 } } } int main() { int t; scanf("%d", &t); memset(mp, 0, sizeof(mp)); init(); while (t--) { len = 0; memset(vis, 0, sizeof(vis)); scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); sort(a, a + n); //字典序排序 dfs(0,0); //第一次传递cur为0时相当于还没开始比较两个,必定成功 printf("%d\n", len); for (int i = 0; i < len; i++) { for (int j = 0; j < n-1; j++) printf("%d ", ans[i][j]); printf("%d\n",ans[i][n-1]);//输出有点严格,不能多空格 } } return 0; }