您的位置:首页 > 其它

zoj 386 4000 1 Valid Pattern Lock

2015-04-14 22:45 543 查看
DFS 搜索时带着方向一起 在碰到已经走过的点时 不能继续16个方向搜索 只能按照原来的方向搜下一个点

不能走的点标记为0  能走的点标记为1 走过的点标记为2

写的好搓啊(笑)

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int T,n;
struct node
{
int num[77]={0};
};
node ans[150000];
int vis[7][7];
int map[7][7];
int tans[77];
int cnt;
int dre[18][2]= {{1,0},{0,1},{1,1},{-1,1},{1,-1},{-1,0},{0,-1},{-1,-1},{2,1},{-2,1},{2,-1},{1,2},{-1,2},{-2,-1},{1,-2},{-1,-2}};
bool check(int x,int y)
{
if(x>0&&x<=3&&y>0&&y<=3)
return 1;
return 0;
}
void init()
{
int i,j,k;
k=1;
for(i=1; i<=3; i++)
for(j=1; j<=3; j++)
{
map[i][j]=k++;
}
}
bool cmp(node a,node b)
{
int i;
for(i=0;i<n;i++)
if(a.num[i]!=b.num[i])
return a.num[i]<b.num[i];
}
void dfs(int x,int y,int p,int s,int l,bool flag)
{
int i;
int a,b;
if(flag&&vis[x][y]==1)
s++;
if(l>13)
return;
if(s==n-1)
{
cnt++;
for(i=0; i<s; i++)
ans[cnt].num[i]=tans[i];
ans[cnt].num[i]=map[x][y];
return;
}
if(vis[x][y]==2)
{
if(check(x+dre[p][0],y+dre[p][1]))
dfs(x+dre[p][0],y+dre[p][1],p,s,l+1,1);
}
else if(vis[x][y]==1)
{
vis[x][y]=2;
tans[s]=map[x][y];
for(i=0; i<16; i++)
{
a=x+dre[i][0];
b=y+dre[i][1];
if(check(a,b))
{
if(vis[a][b]==1)
{

dfs(a,b,i,s+1,l+1,0);
}
else if(vis[a][b]==2)
dfs(a,b,i,s,l+1,0);
}
}
vis[x][y]=1;
}
}
int main()
{
scanf("%d",&T);
init();
while(T--)
{
int i,j,k,l;
memset(vis,0,sizeof(vis));
//memset(ans,0,sizeof(ans));
scanf("%d",&n);
for(i=0; i<n; i++)
{
scanf("%d",&l);
if(l%3==0)
vis[l/3][3]=1;
else
vis[l/3+1][l%3]=1;
}
cnt=0;
for(i=1; i<=3; i++)
for(j=1; j<=3; j++)
{
//memset(tans,0,sizeof(tans));
if(vis[i][j])
dfs(i,j,-1,0,0,0);
}
sort(ans+1,ans+1+cnt,cmp);
printf("%d\n",cnt);
for(i=1; i<=cnt; i++)
{
for(j=0; j<n; j++)
{
if(j==0)
printf("%d",ans[i].num[j]);
else
printf(" %d",ans[i].num[j]);
ans[i].num[j]=0;
}
printf("\n");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  zoj dfs