您的位置:首页 > 其它

ZOJ3861 Valid Pattern Lock

2015-04-14 15:55 183 查看
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=150302

题意:给定一个九宫格,给定一些能走的数字,走法按照手机图案的解锁方法来解锁,起点不定,求合法路线的总数并按照字典序输出他们

思路:暴力破解+DFS。刚开始的想法是把路线看成二维,一条一条判断是否合法,这种方法最大的问题就是会超时,而且例如1->3>1>4的路线不好表示,要假定一个点只能经过两次,搜索的深度瞬间增加了n个指数级。实际上由于点数小,可以把路线看成一维,只是有些路线在某些情况下不合法,穷举即可。莫名其妙的做了很久。

错误源码:

#include <iostream>

#include <cstdio>

#include <string>

#include <string.h>

#include <map>

#include <vector>

#include <cstdlib>

#include <algorithm>

#include <cmath>

#include <queue>

#include <set>

#include <stack>

#include <functional>

#include <fstream>

#include <sstream>

#include <iomanip>

#include <numeric>

#include <cassert>

#include <bitset>

#include <stack>

#include <ctime>

#include <list>

#define INF 0x7fffffff

#define max3(a,b,c) (max(a,b)>c?max(a,b):c)

#define min3(a,b,c) (min(a,b)<c?min(a,b):c)

#define mem(a,b) memset(a,b,sizeof(a))

using namespace std;

int const MAXN = 10;

int use[MAXN],uu[MAXN];

int org[MAXN];

int vis[4][4];

int re[MAXN];

int rec[362880+1];

int n;

int dy[12] = {-2,-1,0,1,2,-1,1,-2,-1,0,1,2};

int dx[12] = {-1,-1,-1,-1,-1,0,0,1,1,1,1,1};

int dir[MAXN] = {1,1,1e1,1e2,1e3,1e4,1e5,1e6,1e7,1e8};

int num,total;///num for all rec,total for not repeaty ones.

bool valid(int a)

{

if(a<1 || a>3)

return false;

return true;

}

bool cmp(int a,int b)

{

return a<b;

}

bool equ(int a[],int b[])

{

int i;

for(i=0; i<n; i++)

if(a[i]!=b[i])

return false;

return true;

}

int X(int i)

{

return i%3?i/3+1:i/3;

}

int Y(int i)

{

return i%3?i%3:3;

}

void init()

{

num = total = 0;

memset(rec,0,sizeof(rec));

memset(use,0,sizeof(use));

int i,temp;

for(i=0; i<n; i++){

scanf("%d", &temp);

use[temp] = 1;

org[i] = temp;

}

sort(org,org+n);

}

void dfs(int now,int mark)

{

int i;

if(mark==n){

// if(num>0 && equ(rec[num],re))

// return;

num++;

for(i=0; i<n; i++){

rec[num]= rec[num]*10 + re[i];

}

// printf("\nnum = %d\n",num);

// for(i=0; i<n; i++)

// printf("%d ",re[i]);

// printf("\n\n");

}

// printf("now = %d mark = %d\n",now,mark);

for(i=0; i<12; i++){

// printf("now = %d\n",now);

int tx = X(now)+dx[i];

int ty = Y(now)+dy[i];

int t = (tx-1)*3 + ty;

// printf("first tx = %d ty = %d t = %d\n",tx,ty,t);

if(valid(tx)&&valid(ty) && use[t] && vis[tx][ty]<2){

// printf("second tx = %d ty = %d t = %d\n",tx,ty,t);

// for(i=0; i<mark; i++)

// printf("%d ",re[i]);

// printf("\n");

vis[tx][ty]++;

if(uu[t]==0){

uu[t] = 1;

re[mark] = t;

dfs(t,mark+1);

uu[t] = 0;

}

else

dfs(t,mark);

vis[tx][ty]--;

}

}

}

void solve()

{

int i,j;

memset(vis,0,sizeof(vis));

memset(uu,0,sizeof(uu));

for(i=0; i<n ;i++){

int t = org[i];

int tx = X(t);

int ty = Y(t);

vis[tx][ty] = 1;

re[0] = t;

uu[t] = 1;

// printf("org = %d\n",org[i]);

dfs(t,1);

vis[tx][ty] = 0;

uu[t] = 0;

}

sort(rec,rec+num,cmp);

for(i=1; i<=num; i++)

if(rec[i]!=rec[i-1])

total++;

printf("%d\n",total);

for(i=1; i<=num; i++){

if(i==0 ||(i>0 && rec[i-1]!=rec[i])){

int f = 1;

int tt = rec[i];

for(j=0; j<n; j++){

if(f) f=0;

else printf(" ");

printf("%d",tt/dir[n-j]);

tt = tt%dir[n-j];

// printf("\nrec = %d\n",rec[i]);

}

// printf("%d",rec[i]);

printf("\n");

}

}

}

int main()

{

int t;

scanf("%d", &t);

while(t--){

scanf("%d", &n);

init();

solve();

}

return 0;

}

AC源码:

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

using namespace std;

int const MAXN = 500000;

int dir[2] = {-1,1};

int rec[MAXN][10],org[10],vis[10],re[10];

int n,num;

bool equ(int a[],int b[])

{

int i;

for(i=0; i<n; i++)

if(a[i]!=b[i])

return false;

return true;

}

bool valid(int a[])

{

int tvis[10];

memset(tvis,0,sizeof(tvis));

for(int i=0; i<n; i++){

if(a[i]>9 || a[i]<1)

return false;

for(int j=0; j<2; j++){

if(a[i]==1 && ((a[i+dir[j]]==3&&tvis[2]==0) || (a[i+dir[j]]==9&&tvis[5]==0) || (a[i+dir[j]]==7&&tvis[4]==0)))

return false;

if(a[i]==2 && ((a[i+dir[j]]==8&&tvis[5]==0)))

return false;

if(a[i]==3 && ((a[i+dir[j]]==7&&tvis[5]==0) || (a[i+dir[j]]==9&&tvis[6]==0)))

return false;

if(a[i]==4 && ((a[i+dir[j]]==6&&tvis[5]==0)))

return false;

if(a[i]==7 && ((a[i+dir[j]]==9&&tvis[8]==0)))

return false;

}

tvis[a[i]] = 1;

}

// puts("sdas\n");

return true;

}

void init()

{

memset(vis,0,sizeof(vis));

num = 0;

int i;

scanf("%d",&n);

for(i=0; i<n; i++)

scanf("%d",&org[i]);

sort(org,org+n);

}

void dfs(int cnt)

{

int i;

if(cnt == n+1){

if(valid(re) && (num==0 || (num>0 && !equ(re,rec[num-1])))){

for(i=0; i<n; i++)

rec[num][i] = re[i];

// printf("num = %d\n",num);

num++;

}

return;

}

for(i=0; i<n; i++){

int t = org[i];

if(vis[t]==0){

vis[t] = 1;

re[cnt-1] = t;

dfs(cnt+1);

vis[t] = 0;

}

}

}

void solve()

{

dfs(1);

printf("%d\n",num);

int i,j;

// printf("%d\n",num);

for(i=0; i<num; i++){

int f = 1;

// puts("dasda\n");

for(j=0; j<n; j++){

if(f) f=0;

else printf(" ");

printf("%d",rec[i][j]);

}

printf("\n");

}

}

int main()

{

int t; scanf("%d",&t);

while(t--){

init();

solve();

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: