ZOJ14选拔赛——DFS+暴力——Valid Pattern Lock

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:

  • A pattern can be represented using the sequence of points which it‘s touching for the first time (in the same order of drawing the pattern). And we call those points as active points.
  • For every two consecutive points A and B in the pattern representation, if the line segment connecting A and B passes through some other points, these points must be in the sequence also and comes before A and B, otherwise the pattern will be invalid.
  • In the pattern representation we don‘t mention the same point more than once, even if the pattern will touch this point again through another valid segment, and each segment in the pattern must be going from a point to another point which the pattern didn‘t touch before and it might go through some points which already appeared in the pattern.

Now you are given n active points, you need to find the number of valid pattern locks formed from those active points.

Input

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.

Output

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.

Sample Input

1
3
1 2 3

Sample Output

4
1 2 3
2 1 3
2 3 1
3 2 1


Author: LIN, Xi
Source: The 15th Zhejiang University Programming Contest

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n,x;
const int MAX = 500000;
int ans[11],res[MAX][11],a[11],vis[11];
bool ok(int m)
{
    int flag[11];
    for(int i = 0 ; i <= 10; i++)
        flag[i] = 0;
    for(int i = 1; i <= n ; i++)
    {
        flag[res[m][i]] = 1;
        if((res[m][i] == 1 && res[m][i+1] == 9 && flag[5] == 0)|| (res[m][i] == 9 && res[m][i+1] == 1 && flag[5] == 0) ||
                (res[m][i] == 1 && res[m][i+1] == 3 && flag[2] == 0)|| (res[m][i] == 3 && res[m][i+1] == 1 && flag[2] == 0) ||
                (res[m][i] == 1 && res[m][i+1] == 7 && flag[4] == 0)|| (res[m][i] == 7 && res[m][i+1] == 1 && flag[4] == 0) ||
                (res[m][i] == 2 && res[m][i+1] == 8 && flag[5] == 0)|| (res[m][i] == 8 && res[m][i+1] == 2 && flag[5] == 0) ||
                (res[m][i] == 4 && res[m][i+1] == 6 && flag[5] == 0)|| (res[m][i] == 6 && res[m][i+1] == 4 && flag[5] == 0) ||
                (res[m][i] == 3 && res[m][i+1] == 9 && flag[6] == 0)|| (res[m][i] == 9 && res[m][i+1] == 3 && flag[6] == 0) ||
                (res[m][i] == 7 && res[m][i+1] == 9 && flag[8] == 0)|| (res[m][i] == 9 && res[m][i+1] == 7 && flag[8] == 0) ||
                (res[m][i] == 3 && res[m][i+1] == 7 && flag[5] == 0)|| (res[m][i] == 7 && res[m][i+1] == 3 && flag[5] == 0) )
            return 0;
    }
    return 1;
}

void DFS(int cnt)
{
    if(cnt == n + 1)
    {
        x++;
        for(int i = 1; i <= n ; i++)
            res[x][i] = ans[i];
        return ;
    }
    for(int i = 1; i <= n; i++)
    {
        if(!vis[a[i]])
        {
            ans[cnt] = a[i];
            vis[a[i]] = 1;
            DFS(cnt+1);
            vis[a[i]] = 0;
        }
    }
}
int main()
{

    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(res, -1, sizeof(res));
        scanf("%d",&n);
        for(int i = 1; i <= n ; i++)
            scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        x = 0;
        memset(vis, false, sizeof(vis));
        DFS(1);

        int temp = x;
        for(int i = 1; i <= temp; i++)
        {
            if(ok(i) == 0)
                x--;
        }
        printf("%d\n",x);
        for(int i = 1; i <= temp ; i++)
        {
            if(ok(i))
            {
                for(int j = 1; j < n ; j++)
                    printf("%d ",res[i][j]);
                printf("%d\n",res[i][n]);
            }
        }
    }
    return 0;
}

主要是全排列的算法:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = 500000;
int n,x;
int a[11],ans[11],res[MAX][11],vis[11];
void DFS(int cnt)
{
  if(cnt == n + 1){
     x++;
    for(int i = 1; i <= n ; i++)
       res[x][i] = ans[i];
   return ;
  }
 for(int i = 1; i <= n; i++){
        if(!vis[i]){//用vis[i]或者vis[a[i]]要看数的大小,因为遍历的是数的个数,如果数很大那么这个循环明显不够
           ans[cnt] = a[i];
           vis[i] = 1;
           DFS(cnt+1);
           vis[i] = 0;
        }
     }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        memset(res,-1,sizeof(res));
        memset(vis,0,sizeof(vis));
        for(int i = 1; i <= n ;i++)
            scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        x = 0;
        DFS(1);
        printf("%d\n",x);
        for(int i = 1; i <= x; i++){
            for(int j = 1 ; j < n ;j++)
                printf("%d ",res[i][j]);
                printf("%d\n",res[i][n]);
        }
    }
    return 0;
}

时间: 2024-10-07 04:08:11

ZOJ14选拔赛——DFS+暴力——Valid Pattern Lock的相关文章

ZOJ3861:Valid Pattern Lock(DFS)

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 u

ZOJ 3861 Valid Pattern Lock DFS

每个点有16种方向,向某个方向走一步或者两步,dfs把找到的数都存下来就可以了..... Valid Pattern Lock Time Limit: 2 Seconds      Memory Limit: 65536 KB 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

ZOJ - 3861 Valid Pattern Lock(dfs或其他,两种解法)

Valid Pattern Lock Time Limit: 2000MS   Memory Limit: 65536KB   64bit IO Format: %lld & %llu Submit Status Description Pattern lock security is generally used in Android handsets instead of a password. The pattern lock can be set by joining points on

DFS+模拟 ZOJ 3861 Valid Pattern Lock

题目传送门 1 /* 2 题意:手机划屏解锁,一笔连通所有数字,输出所有可能的路径: 3 DFS:全排列 + ok () 判断函数,去除一些不可能连通的点:) 4 */ 5 #include <cstdio> 6 #include <iostream> 7 #include <algorithm> 8 #include <cstring> 9 #include <string> 10 #include <map> 11 #includ

Valid Pattern Lock

Time Limit: 2 Seconds      Memory Limit: 65536 KB 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 regis

解题报告 之 ZOJ3861 Valid Pattern Lock

解题报告 之 ZOJ3861 Valid Pattern Lock Description 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 registere

2016 省热身赛 Valid Pattern Lock

Valid Pattern Lock Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Description 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 matr

zoj 3861 Valid Pattern Lock(以及自己对dfs的一些理解)

解法:先将每个点之间的可达性用c[][]记录,为0的话代表可以直接走到.但是如果要进行像3 1 2 这样的走法的话必须要先经过他们中间的点2,否则是不能走的. 用c[i][j]记录i和j之间必须要经过的点.然后进行dfs搜索即可. 经过这道题,自己对dfs的递归过程又有了更加深刻的了解.一开始的时候对dfs里面的参数有些疑虑,-->像这样dfs(s[0],0),但是这样的话,每次都要先判断c[x][s[i]] 这样是错误的.dfs(0,0)的话,因为0与1~9都是可以直接到达的(0是自己添加的)

[水题+dfs] zoj 3861 Valid Pattern Lock

题意: 给n个不同的整数(3<=n<=9),问你能绘制出多少种解锁的方案. 输出方案数,以及按字典序输出每种方案. 思路: 一个很水的dfs全排列,加上特判就好了. 特判就是1->9的话就必定经过5等. 这里要注意的是. 中间所经过的数字是必须存在的. 比如要想1->9就必须有5. 5要么被用过,要么就经过5 例子就是 1 3 5 9这四个数. 实际的方案是只有2种 3 5 1 9 和 3 5 9 1 然后就是输入完排下序,保证字典序. 最后就是弱太弱了,写了2个dfs一个算个数,