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 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

题目描述 :
读题读了半天,没读懂,真对自己无语,能不能灵活点,孩子。给你一张图,如图所示,然后给你一些点,将这些点相连,中途不经过其他的点可直接相连,如果经过其他的点的话,那么这些点之前已经
被连过(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.)。
想法是深搜,但是有两个点需要注意,下一步的选择,怎么去处理。由于定义的状态是位置,所以无脑地枚举了24个位置,并且判断相连的点有无经过其他的点,也是枚举。
太无脑了,我们可以把数字定义为状态(其实想到了跟用深搜生成排列差不多,可是受到图的干扰,以后要想清楚,抽象好问题),然后枚举下一个可以到达的点。
由于是要按照字典序输出,先将a数组排序。接下来就是对(然后给你一些点,将这些点相连,中途不经过其他的点可直接相连,如果经过其他的点的话,那么这些点之前已经
被连过)这句话的处理。既然要能相连,要么不经过其它点,要么经过已经访问过的点。我们可以将两种情形转化为一种情况,能相连的不经过其他点的,中间给他加上已经
访问过的点,那么所有能相连的点中间都要有访问过的点,以后每次只需判断这种情况就可以。
通过预处理,将要判断的情况减少。
最后再说一句,第一次遇到这种格式错误,注意一下。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 150000
using namespace std; int n;
int a[][];
int visit[];
int sum;
int _result[maxn][];
int result[maxn];
int b[];
void init()
{
memset(_result,,sizeof(_result));
sum=;
}
void dfs(int x,int _add)
{
if(_add==n)
{
sum+=;
for(int i=;i<n;i++)
_result[sum][i]=result[i];
return ;
}
for(int i=;i<=n;i++)
{
if(visit[ a[x][b[i]] ]== && visit[b[i]]==)
{
visit[b[i]]=;
// _visit[b[i]]=1;
result[_add]=b[i];
dfs(b[i],_add+);
visit[b[i]]=;
// _visit[b[i]]=0;
}
}
} int main()
{
/* for(int i=0;i<24;i++) {
for(int j=0;j<2;j++)
printf("%d ",walk[i][j]);
printf("\n");
}*/
for(int i=;i<;i++)
for(int j=;j<;j++)
a[i][j]=;
memset(visit,,sizeof(visit));
visit[]=;
a[][]=;
a[][]=; a[][]=;
a[][]=; a[][]=;
a[][]=; a[][]=;
a[][]=; a[][]=;
a[][]=; a[][]=;
a[][]=; a[][]=;
a[][]=; a[][]=;
a[][]=; int T;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d",&n);
int data;
for(int i=;i<=n;i++)
{
scanf("%d",&b[i]);
}
sort(b+,b+n+); for(int i=;i<=n;i++)
{
result[]=b[i];
visit[b[i]]=;
dfs(b[i],);
visit[b[i]]=;
} printf("%d\n",sum);
for(int i=;i<=sum;i++)
{
printf("%d",_result[i][]);
for(int j=;j<n;j++)
printf(" %d",_result[i][j]);
printf("\n");
} } return ;
}

下面是没有预处理的减少判断的,而且傻逼了的想法。

不过可以进行优化,判断下一个状态与当前状态之间有无其他点,

如果没有可以访问下一个点,如果有,判断是否被访问。而判断是否

被访问,可以通过预处理,判断只需O(1)时间,极大简化代码,缩短时间。

在过程中判断,情况太多。

#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 100000
using namespace std; int a[][];;
int n;
int visit[][];
int sum;
int _result[maxn][];
int result[maxn];
int t1,t2;
int walk[][]={
-,-, -,-, -,, -,, -,,
-,-, -,-, -,, -,, -,,
,-, ,-, ,, ,,
,-, ,-, ,, ,, ,,
,-, ,-, ,, ,, ,
};
void init()
{
memset(visit,,sizeof(visit));
for(int i=;i<;i++)
for(int j=;j<;j++)
a[i][j]=-;
memset(_result,,sizeof(_result));
sum=;
t1=;
t2=;
}
void dfs(int x,int y,int _add)
{
if(_add==n)
{
sum+=;
for(int i=;i<n;i++)
_result[sum][i]=result[i];
return ;
}
int xx,yy;
for(int i=;i<;i++)
{
xx=x+walk[i][];
yy=y+walk[i][];
if(xx>= && xx<= && yy>= && yy<= && a[xx][yy]!=-)
{
if(x==xx && yy-y==)
{
if(visit[x][y+]==)
continue ;
else
{
result[_add]=a[xx][yy];
dfs(xx,yy,_add+);
}
}
else if(x==xx && y-yy==)
{
if(visit[x][y-]==)
continue ;
else
{
result[_add]=a[xx][yy];
dfs(xx,yy,_add+);
} }
else if(y==yy && xx-x==)
{
if(visit[x][x+]==)
continue ;
else
{
result[_add]=a[xx][yy];
dfs(xx,yy,_add+);
}
}
else if(y==yy && x-xx==)
{
if(visit[x][x-]==)
continue ;
else
{
result[_add]=a[xx][yy];
dfs(xx,yy,_add+);
}
} else if(
(x== && y== && xx== && yy==)
|| (x== && y== && xx== && yy==)
|| (x== && y== && xx== && yy==)
|| (x== && yy== && xx== && yy==)
)
{
if(visit[][]==)
continue ;
else
{
result[_add]=a[xx][yy];
dfs(xx,yy,_add+);
}
} else if(visit[xx][yy]==)
{
visit[xx][yy]=;
result[_add]=a[xx][yy];
dfs(xx,yy,_add+);
visit[xx][yy]=;
}
}
}
} int main()
{
/* for(int i=0;i<24;i++) {
for(int j=0;j<2;j++)
printf("%d ",walk[i][j]);
printf("\n");
}*/ int T;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d",&n);
int data;
for(int i=;i<=n;i++)
{
scanf("%d",&data);
if(data==)
a[][]=data;
if(data==)
a[][]=data;
if(data==)
a[][]=;
if(data==)
a[][]=;
if(data==)
a[][]=;
if(data==)
a[][]=;
if(data==)
a[][]=;
if(data==)
a[][]=;
if(data==)
a[][]=;
}
for(int i=;i<=;i++)
for(int j=;j<=;j++)
{
if(a[i][j]!=-)
{
result[]=a[i][j];
visit[i][j]=;
dfs(i,j,);
visit[i][j]=;
}
}
printf("%d\n",sum);
for(int i=;i<=sum;i++)
{
printf("%d",_result[i][]);
for(int j=;j<n;j++)
printf(" %d",_result[i][j]);
printf("\n");
} } return ;
}
												

zoj 3861(dfs)的更多相关文章

  1. DFS+模拟 ZOJ 3861 Valid Pattern Lock

    题目传送门 /* 题意:手机划屏解锁,一笔连通所有数字,输出所有可能的路径: DFS:全排列 + ok () 判断函数,去除一些不可能连通的点:) */ #include <cstdio> ...

  2. ZOJ 3861 - Valid Pattern Lock

    3861 - Valid Pattern Lock Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & ...

  3. ACM学习历程—ZOJ 3861 Valid Pattern Lock(dfs)

    Description Pattern lock security is generally used in Android handsets instead of a password. The p ...

  4. POJ 1979 Red and Black (zoj 2165) DFS

    传送门: poj:http://poj.org/problem?id=1979 zoj:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problem ...

  5. HDU 1010 Tempter of the Bone (ZOJ 2110) DFS+剪枝

    传送门: HDU:http://acm.hdu.edu.cn/showproblem.php?pid=1010 ZOJ:http://acm.zju.edu.cn/onlinejudge/showPr ...

  6. POJ 1562 Oil Deposits (HDU 1241 ZOJ 1562) DFS

    现在,又可以和她没心没肺的开着玩笑,感觉真好. 思念,是一种后知后觉的痛. 她说,今后做好朋友吧,说这句话的时候都没感觉.. 我想我该恨我自己,肆无忌惮的把她带进我的梦,当成了梦的主角. 梦醒之后总是 ...

  7. zoj 1004 dfs

    想多了!以为一直dfs所有的情况会超时,所以直接忽略了,就自己想了一个优化的算法,最后测试结果对了,但是wa了,自己写算法很容易考虑不周的,还是在最后没有办法的时候在考虑自己的算法吧!!!简单的dfs ...

  8. 浙江大学2015年校赛B题 ZOJ 3861 Valid Pattern Lock

    这道题目是队友写的,貌似是用暴力枚举出来. 题意:给出一组数,要求这组数在解锁的界面可能的滑动序列. 思路:按照是否能够直接到达建图,如1可以直接到2,但是1不能直接到3,因为中间必须经过一个2. 要 ...

  9. ZOJ - 2477 dfs [kuangbin带你飞]专题二

    注意输入的处理,旋转操作打表.递增枚举可能步数,作为限制方便找到最短路. AC代码:90ms #include<cstdio> #include<cstring> char m ...

随机推荐

  1. UVA11090 Going in Cycle!! 【SPFA】

    题意:求一个无向图的边权平均值最小的环 思路:假设环中Σwi/t<ans 那变形一下就是Σwi<ans*t → Σ(wi-ans)< 0 这样就可以二分答案做了 #include & ...

  2. 【贪心+二分】codeforces D. Magazine Ad

    codeforces.com/contest/803/problem/D [题意] 给定一个字符串,字符串里可能有空格和连字符‘-’,空格和连字符的意义是一样的,都表示:能在那个位置把字符串分成两部分 ...

  3. 反编译sencha toucha打包的apk文件,修改应用名称支持中文以及去除应用标题栏

    一.去除安卓应用标题栏 sencha touch打包android安装包,去掉标题栏titlebar的简单方法 (有更复杂更好的方法,参看"二.利用反编译修改apk的应用名称为中文" ...

  4. Linux kernel 内核学习路线

    看了下各位大神的推荐路线,总结如下: 0. 跟着项目走: 1. 学会用.熟练用linux系统: 2. Linux Kernel Development. 3. Understanding the Li ...

  5. python学习之-- 进程 和 线程

    python 进程/线程详解 进程定义:以一个整体的形式暴露给操作系统管理,它里面包含对各种资源的调用,内存的管理,网络接口的调用等等,对各种资源管理的集合,就可以叫做一个进程. 线程定义:线程是操作 ...

  6. python学习之-- 面向对象

    面向对象(简写:OOP) 面向对象编程定义:利用类和对象来创建各种模型,来实现对真实世界的描述. 优点:使程序更容易理解和维护以及扩展代码. 类定义:用来描述具有相同的属性和方法的对象的集合.(简单讲 ...

  7. python学习之 - re模块

    re模块功能:实现字符串匹配. 元字符 描述\ 将下一个字符标记符.或一个向后引用.或一个八进制转义符.例如,“\\n”匹配\n.“\n”匹配换行符.序列“\\”匹配“\”而“\(”则匹配“(”.即相 ...

  8. [Bzoj3668][Noi2014]起床困难综合症(位运算)

    3668: [Noi2014]起床困难综合症 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2612  Solved: 1500[Submit][St ...

  9. [Bzoj2286][Sdoi2011]消耗战(虚树模板题附讲解)

    2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 4896  Solved: 1824[Submit][Statu ...

  10. loj6158 A+B Problem (扩展KMP)

    题目: https://loj.ac/problem/6158 分析: 先把S串逆置,就是从低位向高位看 我们再弄个T串,S串前面有x个连续的0,那么T串前面也有x个连续的0 第x+1位,满足S[x+ ...