程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> POJ 3083 Children of the Candy Corn

POJ 3083 Children of the Candy Corn

編輯:C++入門知識

Children of the Candy Corn
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 7104   Accepted: 3108
Description

The cornfield maze is a popular Halloween treat. Visitors are shown the entrance and must wander through the maze facing zombies, chainsaw-wielding psychopaths, hippies, and other terrors on their quest to find the exit.      www.2cto.com

One popular maze-walking strategy guarantees that the visitor will eventually find the exit. Simply choose either the right or left wall, and follow it. Of course, there's no guarantee which strategy (left or right) will be better, and the path taken is seldom the most efficient. (It also doesn't work on mazes with exits that are not on the edge; those types of mazes are not represented in this problem.)

As the proprieter of a cornfield that is about to be converted into a maze, you'd like to have a computer program that can determine the left and right-hand paths along with the shortest path so that you can figure out which layout has the best chance of confounding visitors.
Input

Input to this problem will begin with a line containing a single integer n indicating the number of mazes. Each maze will consist of one line with a width, w, and height, h (3 <= w, h <= 40), followed by h lines of w characters each that represent the maze layout. Walls are represented by hash marks ('#'), empty space by periods ('.'), the start by an 'S' and the exit by an 'E'.

Exactly one 'S' and one 'E' will be present in the maze, and they will always be located along one of the maze edges and never in a corner. The maze will be fully enclosed by walls ('#'), with the only openings being the 'S' and 'E'. The 'S' and 'E' will also be separated by at least one wall ('#').

You may assume that the maze exit is always reachable from the start point.
Output

For each maze in the input, output on a single line the number of (not necessarily unique) squares that a person would visit (including the 'S' and 'E') for (in order) the left, right, and shortest paths, separated by a single space each. Movement from one square to another is only allowed in the horizontal or vertical direction; movement along the diagonals is not allowed.
Sample Input

2
8 8
########
#......#
#.####.#
#.####.#
#.####.#
#.####.#
#...#..#
#S#E####
9 5
#########
#.#.#.#.#
S.......E
#.#.#.#.#
#########
Sample Output

37 5 5
17 17 9
Source

South Central USA 2006
對於這個題,昨天晚上靜下心來好好想想發現對於求最短的距離bfs就可以,這是很簡單的,但是怎麼才能繞牆呢,看了看discuss大部分都是用dfs,我想了想不太會,然後就在那畫圖,發現這個題其實不用dfs就可以,繞牆到目的地,只會有一條路徑,只需要記錄剛走過的兩個點,判斷走的方向 ,對於每種走的方向考慮的情況都是一樣的,以沿著左邊的牆向上走為例,主要有以下幾種情況
1 左邊不是牆了,這個時候就需要向左走一個。
2 左邊是牆,這個時候需要向前走,這個時候兩種情況 (1):前方不是牆直接向前走就可以了
                                                                                        (2):前方是牆,這個時候就要右拐,也分兩種情況:
                                                                                                                  《1》 右拐不是牆,直接走可以了。
                                                                                                                   《2》 右拐是牆,這個時候就要退回去了
靠著左邊的牆走,會有四種方向,這四種方向考慮的情況都是上面那樣,對於向左拐還是右拐,可以開數組,存儲一下方向,到時候直接用就行。
這段代碼是我剛寫出的代碼,發現向左和向右處理的都差不多,就是換了換數組,就做了簡化處理。兩段代碼都貼一下吧
[cpp] 
lude <iostream> 
#include <string.h> 
using namespace std; 
int vex1[]={0,0,-1,1},vey1[]={-1,1,0,0}; 
int vex2[]={0,0,1,-1},vey2[]={1,-1,0,0}; 
int vectorx[]={-1,1,0,0},vectory[]={0,0,1,-1}; 
int status[50][50],a[50][50],res1,res2,res3,pos_stax,pos_stay,pos_endx,pos_endy; 
int n,m; 
int main() 

    void deal_left(); 
    void deal_right(); 
    void deal(); 
    int i,j,s,t; 
    char c; 
    cin>>t; 
    while(t--) 
    { 
        cin>>m>>n; 
        for(i=1;i<=n;i++) 
        { 
            for(j=1;j<=m;j++) 
            { 
                cin>>c; 
                if(c=='#') 
                { 
                    a[i][j]=0; 
                }else if(c=='S') 
                { 
                    a[i][j]=0; 
                    pos_stax=i; pos_stay=j; 
                }else if(c=='E') 
                { 
                    a[i][j]=1; 
                    pos_endx=i; pos_endy=j; 
                }else if(c=='.') 
                { 
                    a[i][j]=1; 
                } 
            } 
        } 
        deal_left(); 
        deal_right(); 
        deal(); 
        cout<<res1<<" "<<res2<<" "<<res3<<endl; 
    } 
    return 0; 

void deal_left() 

    int i,j,x1,y1,x2,y2,x3,y3,s,x4,y4,t,temp1,temp2; 
    s=2; x1=pos_stax; y1=pos_stay; 
    for(i=0;i<=3;i++) 
    { 
        x2=x1+vex1[i]; y2=y1+vey1[i]; 
        if(x2>=1&&x2<=n&&y2>=1&&y2<=m&&a[x2][y2]) 
        { 
            break; 
        } 
    } 
    while(1) 
    { 
        x4=x2-x1; y4=y2-y1; 
        if(x4<0&&y4==0) 
        { 
            t=0; 
        }else if(x4>0&&y4==0) 
        { 
            t=1; 
        }else if(x4==0&&y4>0) 
        { 
            t=2; 
        }else if(x4==0&&y4<0) 
        { 
            t=3; 
        } 
        if(a[x2+vex1[t]][y2+vey1[t]]) 
        { 
            x1=x2; y1=y2; 
            x2=x2+vex1[t]; y2=y2+vey1[t]; 
            s+=1; 
        }else 
        { 
            x3=x2+vectorx[t]; y3=y2+vectory[t]; 
            if(a[x3][y3]) 
            { 
                x1=x2; y1=y2; 
                x2=x3; y2=y3; 
            }else 
            { 
                x3=x2+vex2[t]; y3=y2+vey2[t]; 
                if(a[x3][y3]) 
                { 
                    x1=x2; y1=y2; 
                    x2=x3; y2=y3; 
                }else 
                { 
                    temp1=x1; temp2=y1; 
                    x1=x2;    y1=y2; 
                    x2=temp1; y2=temp2; 
                } 
            } 
            s++; 
        } 
        if(x2==pos_endx&&y2==pos_endy) 
        { 
            res1=s; 
            break; 
        } 
    } 

void deal_right() 

    int i,j,x1,y1,x2,y2,x3,y3,s,x4,y4,t,temp1,temp2; 
    int sum=0; 
    s=2; x1=pos_stax; y1=pos_stay; 
    for(i=0;i<=3;i++) 
    { 
        x2=x1+vex1[i]; y2=y1+vey1[i]; 
        if(x2>=1&&x2<=n&&y2>=1&&y2<=m&&a[x2][y2]) 
        { 
            break; 
        } 
    } 
    while(1) 
    { 
        x4=x2-x1; y4=y2-y1; 
        if(x4<0&&y4==0) 
        { 
            t=0; 
        }else if(x4>0&&y4==0) 
        { 
            t=1; 
        }else if(x4==0&&y4>0) 
        { 
            t=2; 
        }else if(x4==0&&y4<0) 
        { 
            t=3; 
        } 
        if(a[x2+vex2[t]][y2+vey2[t]]) 
        { 
            x1=x2; y1=y2; 
            x2=x2+vex2[t]; y2=y2+vey2[t]; 
            s+=1; 
        }else 
        { 
            x3=x2+vectorx[t]; y3=y2+vectory[t]; 
            if(a[x3][y3]) 
            { 
                x1=x2; y1=y2; 
                x2=x3; y2=y3; 
            }else 
            { 
                x3=x2+vex1[t]; y3=y2+vey1[t]; 
                if(a[x3][y3]) 
                { 
                    x1=x2; y1=y2; 
                    x2=x3; y2=y3; 
                }else 
                { 
                    temp1=x1; temp2=y1; 
                    x1=x2;    y1=y2; 
                    x2=temp1; y2=temp2; 
                } 
            } 
            s++; 
        } 
        if(x2==pos_endx&&y2==pos_endy) 
        { 
            res2=s; 
            break; 
        } 
    } 

void deal() 

    int i,j,base,top,x,y,xend,yend; 
    int queue[100000][2]; 
    int sum[50][50]; 
    memset(status,0,sizeof(status)); 
    memset(sum,0,sizeof(sum)); 
    base=top=0; 
    queue[top][0]=pos_stax; queue[top++][1]=pos_stay; 
    sum[pos_stax][pos_stay]=1; status[pos_stax][pos_stay]=1; 
    while(base<top) 
    { 
        x=queue[base][0]; y=queue[base++][1]; 
        for(i=0;i<=3;i++) 
        { 
            xend=x+vex1[i]; yend=y+vey1[i]; 
            if(xend>=1&&xend<=n&¥d>=1&¥d<=m&&!status[xend][yend]&&a[xend][yend]) 
            { 
                sum[xend][yend]=sum[x][y]+1; 
                status[xend][yend]=1; 
                queue[top][0]=xend; queue[top++][1]=yend; 
                if(xend==pos_endx&¥d==pos_endy) 
                { 
                    break; 
                } 
            } 
        } 
        if(i!=4) 
        { 
            break; 
        } 
    } 
    res3=sum[pos_endx][pos_endy]; 

左右方向放在一個函數中處理。
[cpp] 
#include <iostream> 
#include <string> 
using namespace std; 
int bx1[]={0,0,-1,1},by1[]={-1,1,0,0}; 
int bx2[]={0,0,1,-1},by2[]={1,-1,0,0}; 
int vectorx[]={-1,1,0,0},vectory[]={0,0,1,-1}; 
int status[50][50],a[50][50],res1,res2,res3,pos_stax,pos_stay,pos_endx,pos_endy; 
int n,m; 
int main() 

    void deal_left_Or_right(int vex1[5],int vey1[5],int vex2[5],int vey2[5],int &k); 
    void deal(); 
    int i,j,s,t; 
    char c; 
    cin>>t; 
    while(t--) 
    { 
        cin>>m>>n; 
        for(i=1;i<=n;i++) 
        { 
            for(j=1;j<=m;j++) 
            { 
                cin>>c; 
                if(c=='#') 
                { 
                    a[i][j]=0; 
                }else if(c=='S') 
                { 
                    a[i][j]=0; 
                    pos_stax=i; pos_stay=j; 
                }else if(c=='E') 
                { 
                    a[i][j]=1; 
                    pos_endx=i; pos_endy=j; 
                }else if(c=='.') 
                { 
                    a[i][j]=1; 
                } 
            } 
        } 
        deal_left_Or_right(bx1,by1,bx2,by2,res1); 
        deal_left_Or_right(bx2,by2,bx1,by1,res2); 
        deal(); 
        cout<<res1<<" "<<res2<<" "<<res3<<endl; 
    } 
    return 0; 

void deal_left_Or_right(int vex1[5],int vey1[5],int vex2[5],int vey2[5],int &k) 

    int i,j,x1,y1,x2,y2,x3,y3,s,x4,y4,t,temp1,temp2; 
    s=2; x1=pos_stax; y1=pos_stay; 
    for(i=0;i<=3;i++) 
    { 
        x2=x1+vex1[i]; y2=y1+vey1[i]; 
        if(x2>=1&&x2<=n&&y2>=1&&y2<=m&&a[x2][y2]) 
        { 
            break; 
        } 
    } 
    while(1) 
    { 
        x4=x2-x1; y4=y2-y1; 
        if(x4<0&&y4==0) 
        { 
            t=0; 
        }else if(x4>0&&y4==0) 
        { 
            t=1; 
        }else if(x4==0&&y4>0) 
        { 
            t=2; 
        }else if(x4==0&&y4<0) 
        { 
            t=3; 
        } 
        if(a[x2+vex1[t]][y2+vey1[t]]) 
        { 
            x1=x2; y1=y2; 
            x2=x2+vex1[t]; y2=y2+vey1[t]; 
            s+=1; 
        }else 
        { 
            x3=x2+vectorx[t]; y3=y2+vectory[t]; 
            if(a[x3][y3]) 
            { 
                x1=x2; y1=y2; 
                x2=x3; y2=y3; 
            }else 
            { 
                x3=x2+vex2[t]; y3=y2+vey2[t]; 
                if(a[x3][y3]) 
                { 
                    x1=x2; y1=y2; 
                    x2=x3; y2=y3; 
                }else 
                { 
                    temp1=x1; temp2=y1; 
                    x1=x2;    y1=y2; 
                    x2=temp1; y2=temp2; 
                } 
            } 
            s++; 
        } 
        if(x2==pos_endx&&y2==pos_endy) 
        { 
            k=s; 
            break; 
        } 
    } 

void deal() 

    int i,j,base,top,x,y,xend,yend; 
    int queue[100000][2]; 
    int sum[50][50]; 
    memset(status,0,sizeof(status)); 
    memset(sum,0,sizeof(sum)); 
    base=top=0; 
    queue[top][0]=pos_stax; queue[top++][1]=pos_stay; 
    sum[pos_stax][pos_stay]=1; status[pos_stax][pos_stay]=1; 
    while(base<top) 
    { 
        x=queue[base][0]; y=queue[base++][1]; 
        for(i=0;i<=3;i++) 
        { 
            xend=x+bx1[i]; yend=y+by1[i]; 
            if(xend>=1&&xend<=n&¥d>=1&¥d<=m&&!status[xend][yend]&&a[xend][yend]) 
            { 
                sum[xend][yend]=sum[x][y]+1; 
                status[xend][yend]=1; 
                queue[top][0]=xend; queue[top++][1]=yend; 
                if(xend==pos_endx&¥d==pos_endy) 
                { 
                    break; 
                } 
            } 
        } 
        if(i!=4) 
        { 
            break; 
        } 
    } 
    res3=sum[pos_endx][pos_endy]; 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved