poj3083 Children of the Candy Corn dfs 和 bfs 的综合,终于AC了

来源:互联网 发布:和还原精灵类似软件 编辑:程序博客网 时间:2024/04/28 14:49

2014-03-13

TLE后就把输入和输出全改成 scanf( ) 和 printf( ) 了,但还是超时。感觉是搜索最短路径时用的方法太慢了。下面是TLE的代码:

///2014.3.11 - 2014.3.13///poj3083#include <iostream>#include <cstdio>using namespace std;int w,h;               ///记录迷宫的大小char maze[50][50];     ///记录迷宫int start_w,start_h;   ///记录迷宫的开始位置int start_pre;         ///其前一步的相对于现在位置的方向,                            ///0表示在右,1表示在上面,2表示在左边,3是下面bool findmin;          ///标记有没有找到最短路int step;int next_w[4] = {1,0,-1,0};   ///方便走下一步int next_h[4] = {0,-1,0,1};void dfs(int h,int w,int pre,int l_r){    step++;    if( maze[h][w]=='E' ){        return;    }    if( maze[h+next_h[(pre+l_r)%4] ][w+next_w[(pre+l_r)%4] ] !='#' ){        dfs( h+next_h[(pre+l_r)%4], w+next_w[(pre+l_r)%4], (pre+l_r+2)%4,l_r);    }    else if( maze[h+next_h[(pre+l_r*2)%4] ][w+next_w[(pre+l_r*2)%4] ] !='#' ){        dfs( h+next_h[(pre+l_r*2)%4], w+next_w[(pre+l_r*2)%4], (pre+l_r*2+2)%4,l_r);    }    else if( maze[h+next_h[(pre+l_r*3)%4] ][w+next_w[(pre+l_r*3)%4] ] !='#' ){        dfs( h+next_h[(pre+l_r*3)%4], w+next_w[(pre+l_r*3)%4], (pre+l_r*3+2)%4,l_r);    }    else{        dfs( h+next_h[pre], w+next_w[pre], (pre+2)%4,l_r);    }}void bfs(int h,int w,int pre,int deep){    step++;    if( findmin ) return;    if( maze[h][w]=='E' ){        findmin = true;        return;    }    if( deep==step ){        return;    }    if( maze[h+next_h[(pre+1)%4] ][w+next_w[(pre+1)%4] ] !='#' ){        bfs( h+next_h[(pre+1)%4], w+next_w[(pre+1)%4], (pre+1+2)%4,deep);        step--;    }    if( maze[h+next_h[(pre+2)%4] ][w+next_w[(pre+2)%4] ] !='#' ){        bfs( h+next_h[(pre+2)%4], w+next_w[(pre+2)%4], (pre+2+2)%4,deep);        step--;    }    if( maze[h+next_h[(pre+3)%4] ][w+next_w[(pre+3)%4] ] !='#' ){        bfs( h+next_h[(pre+3)%4], w+next_w[(pre+3)%4], (pre+3+2)%4,deep);        step--;    }}void init(){    char c;    scanf("%d%d",&w,&h);    scanf("%c",&c);    for(int i=1 ; i<=h ; i++){        for(int j=1 ; j<=w ; j++){            scanf("%c",&c);            maze[i][j] = c;            if( c=='S' ){                start_w = j;                start_h = i;                if( j==1 )                    start_pre = 2;                else if( j==w )                    start_pre = 0;                else if( i==1 )                    start_pre = 1;                else                    start_pre = 3;            }        }        scanf("%c",&c);    }    step = 0;}int main(){//    freopen("in","r",stdin);//    freopen("out","w",stdout);    int cas;    scanf("%d",&cas);    while( cas-- ){        init();        dfs(start_h,start_w,start_pre,3);        printf("%d ",step);        step = 0;        dfs(start_h,start_w,start_pre,1);        printf("%d ",step);        findmin = false;        int deep;        for(deep=1 ; !findmin ; deep++){            step = 0;            bfs(start_h,start_w,start_pre,deep);        }        printf("%d\n",--deep);    }    return 0;}

 2014-03-17

  这个题折磨了我好几天,知道自己的bfs方法太慢,但是自己太菜了,不知道怎么改。各种不甘心,所以上英语课时找出CSDN上那个很厉害的“小优学姐”的代码研究。(http://blog.csdn.net/lyy289065406/article/details/6647668)

  得到启发思路,从新写代码A掉这一题,废话少说,上代码:

///2014.3.17///poj3083#include <iostream>#include <cstdio>#include <cstring>using namespace std;int W,H;               ///记录迷宫的大小char maze[50][50];     ///记录迷宫int start_w,start_h;   ///记录迷宫的开始位置int start_pre;         ///其前一步的相对于现在位置的方向,                            ///0表示在右,1表示在上面,2表示在左边,3是下面int step;int next_w[4] = {1,0,-1,0};   ///方便走下一步int next_h[4] = {0,-1,0,1};void dfs(int h,int w,int pre,int l_r)  ///l_r变量决定优先左拐还是右拐{    step = 1; ///起点是第一步    while( maze[h][w] != 'E' ){        step++;        if( maze[h+next_h[(pre+l_r)%4] ][w+next_w[(pre+l_r)%4] ] !='#' ){            h = h+next_h[(pre+l_r)%4];            w = w+next_w[(pre+l_r)%4];            pre = (pre+l_r+2)%4;        }        else if( maze[h+next_h[(pre+l_r*2)%4] ][w+next_w[(pre+l_r*2)%4] ] !='#' ){            h = h+next_h[(pre+l_r*2)%4];            w = w+next_w[(pre+l_r*2)%4];            pre = (pre+l_r*2+2)%4;        }        else if( maze[h+next_h[(pre+l_r*3)%4] ][w+next_w[(pre+l_r*3)%4] ] !='#' ){            h = h+next_h[(pre+l_r*3)%4];            w = w+next_w[(pre+l_r*3)%4];            pre = (pre+l_r*3+2)%4;        }        else{            h = h+next_h[pre];            w = w+next_w[pre];            pre = (pre+2)%4;        }    }    printf("%d ",step);}void bfs(int h,int w)  ///建立一个搜索树,'E'的深度就是最少的步数{    int p,q;    p=q=0;        int h_queue[1650];     ///记录搜到的每一步的h坐标    int w_queue[1650];     ///记录搜到的每一步的w坐标    int deep_queue[1650];  ///记录搜到的每一步的深度    bool visited[50][50];    memset(visited,false,sizeof(bool)*50*50);        h_queue[1] = h;    w_queue[1] = w;    deep_queue[1] = 1;    p=0;    q=1;    while( p!=q ){        p++;        if( maze[ h_queue[p] ][ w_queue[p]+1 ]=='.'             && !visited[ h_queue[p] ][ w_queue[p]+1 ]             || maze[ h_queue[p] ][ w_queue[p]+1 ]=='E'){            if(maze[ h_queue[p] ][ w_queue[p]+1 ]=='E'){                printf("%d\n",deep_queue[p]+1 );                break;            }            q++;            visited[ h_queue[p] ][ w_queue[p]+1 ] = true;            h_queue[q] = h_queue[p];            w_queue[q] = w_queue[p]+1;            deep_queue[q] = deep_queue[p]+1;        }        if( maze[ h_queue[p]+1 ][ w_queue[p] ]=='.'             && !visited[ h_queue[p]+1 ][ w_queue[p] ]             || maze[ h_queue[p]+1 ][ w_queue[p] ]=='E'){            if(maze[ h_queue[p]+1 ][ w_queue[p] ]=='E'){                printf("%d\n",deep_queue[p]+1 );                break;            }            q++;            visited[ h_queue[p]+1 ][ w_queue[p] ] = true;            h_queue[q] = h_queue[p]+1;            w_queue[q] = w_queue[p];            deep_queue[q] = deep_queue[p]+1;        }        if( maze[ h_queue[p] ][ w_queue[p]-1 ]=='.'             && !visited[ h_queue[p] ][ w_queue[p]-1 ]             || maze[ h_queue[p] ][ w_queue[p]-1 ]=='E'){            if(maze[ h_queue[p] ][ w_queue[p]-1 ]=='E'){                printf("%d\n",deep_queue[p]+1 );                break;            }            q++;            visited[ h_queue[p] ][ w_queue[p]-1 ] = true;            h_queue[q] = h_queue[p];            w_queue[q] = w_queue[p]-1;            deep_queue[q] = deep_queue[p]+1;        }        if( maze[ h_queue[p]-1 ][ w_queue[p] ]=='.'             && !visited[ h_queue[p]-1 ][ w_queue[p] ]             || maze[ h_queue[p]-1 ][ w_queue[p] ]=='E'){            if(maze[ h_queue[p]-1 ][ w_queue[p] ]=='E'){                printf("%d\n",deep_queue[p]+1 );                break;            }            q++;            visited[ h_queue[p]-1 ][ w_queue[p] ] = true;            h_queue[q] = h_queue[p]-1;            w_queue[q] = w_queue[p];            deep_queue[q] = deep_queue[p]+1;        }    }}void init(){    char c;    scanf("%d%d",&W,&H);    scanf("%c",&c);    for(int i=1 ; i<=H ; i++){    ///读入迷宫        for(int j=1 ; j<=W ; j++){            scanf("%c",&c);            maze[i][j] = c;            if( c=='S' ){      ///找到起点并设置起点信息                start_w = j;                start_h = i;                if( j==1 )                    start_pre = 2;                else if( j==H )                    start_pre = 0;                else if( i==1 )                    start_pre = 1;                else                    start_pre = 3;            }        }        scanf("%c",&c);    }    step = 0;}int main(){    // freopen("in","r",stdin);    // freopen("out","w",stdout);    int cas;    scanf("%d",&cas);    while( cas-- ){        init();  ///初始化工作        dfs(start_h,start_w,start_pre,3); ///优先左拐        dfs(start_h,start_w,start_pre,1); ///优先右拐        bfs(start_h,start_w);  ///最短步数    }    return 0;}

  递归效率太低了,这次深刻体会~
0 0
原创粉丝点击