UVA 225 Golygons(DFS + sort)

来源:互联网 发布:c语言如何输入多个数据 编辑:程序博客网 时间:2024/05/04 17:09

题目给出一个整数N和M个点,每次可以在一个方向行走K(当前以行走的次数)步,且行走完毕后必须90度转向,并且不能行走到题目给出的点上,问是否存在某种行走次序,使得经过N次行走后又回到原点,如果有,按字典序输出行走步骤,并输出次序的个数.

刚开始看到这道题时我就在想是不是可以行走回原点的N值是确定的,于是编写了一个小的测试程序测试了一下,发现确实跟我想的一样,当N<=20时,只有7,8,15,16这四个数在没有任何不能通过的点时依然可以回到原点,剩下的就是模拟行走过程了.

由题知N最多是20,而且中间还经过转向,所以从原点向外走最多也就是200个点,于是可以构造一个400*400的表格,用来存不能经过的点,剩下的就是模拟行走过程了,可以发现行走的过程很像dfs,于是主程序就可以通过递归完成了。

我写的程序运行时间有点长,主要是想节省转向时的判断因而在字符串排序那里花费了很多时间,其实可以直接在递归的次序上直接完成字符串的按字典序输出,时间应该可以减少一半左右,下面给出代码:

#include <cstdio>#include <algorithm>#include <string.h>#include <string>#include <iostream>using namespace std;const int dx[4] = {0,-1,0,1};const int dy[4] = {1,0,-1,0};const char ch[5] = {'n','w','s','e',0};int N,T,K,sum;int vis[500][500]; //vis[250][250] is originalchar s[25];string A[120];void judge(int x,int y,int k,int l){    if (x == 250 && y == 250 && l == N){        s[l] = 0;        A[sum] = s;        sum++;        return;    }    if (l >= N) return ;    int qwe[3] ={k-1,k+1};    for (int qwer  = 0 ;qwer < 2; ++ qwer){        int i = qwe[qwer];        if (i < 0) i = 3;        if (i > 3) i = 0;        int a = x + (l+1)*dx[i], b = y + (l+1)*dy[i];        bool ok = false;        for (int m = min(a,x) ; m <= max(a,x); ++m){            for (int n = min(b,y) ; n <= max(b,y) ; ++ n){                if (vis[m][n] == 1){                    ok = true;                    break;                }            }            if (ok) break;        }        if (ok) continue;        s[l] = ch[i];        if(vis[a][b] == 0) {            vis[a][b] = -1;            judge(a,b,i,l+1);            vis[a][b] = 0;        }    }    return;}int main(){    scanf("%d",&T);    while (T--){        memset(vis,0,sizeof(vis));        sum = 0;        scanf("%d %d",&N,&K);        for (int i = 0 ; i < K ;++ i){            int a,b;            scanf("%d %d",&a,&b);            if (a < -220 || a > 220 || b < -220 || b > 220) continue;            vis[250+a][250+b] = 1;        }        if (N != 7 && N != 8 && N != 15 && N!=16){            printf("Found 0 golygon(s).\n\n");            continue;        }        for (int i = 0 ;i <4 ;++i){            s[0] = ch[i];            judge(250+ dx[i],250+ dy[i],i,1);        }        sort(A,A+sum);        for (int i = 0 ;i < sum; ++i)            cout<<A[i]<<endl;        printf("Found %d golygon(s).\n\n",sum);    }    return 0;}
0 0
原创粉丝点击