poj 3083 Children of the Candy Corn

我要吃糖!!!(^o^)/~


题目大意:
多case,给出cas张地图,’#’代表墙,’.’代表坦坦大道,也就是说你要是不想死的话就好好走’.’吧! >o<
要求输出3个数字,第一个—优先向左靠墙走,第二个—优先向右靠墙走,第三个—最短路


分析:
STMD算法!!!
第三个答案很好说,大家都会,那么优先向左/右走呢???
以优先向左为例吧♪(^∇^*)
我们只要找出方向优先级就好啦
左上右下,按照这个顺序走找到答案即可
(**记得要保存你当前的方向)


代码如下:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=40+5;
int cas,row,columns,maxdep,flag;
int start[2+1],pri[4][2+1],end[2+1];
char str[maxn],chess[maxn][maxn];
bool left(int dep,int x,int y,int dire){
    for(int i=0;i<=3;i++){
        int xx=x+pri[(i+dire+4)%4][1],yy=y+pri[(i+dire+4)%4][2];
        if(xx<1||xx>row||yy<1||yy>columns)
            continue;
        if(chess[xx][yy]=='E'){
            printf("%d ",dep+1),flag=1;
            return true;
        }
        else if(chess[xx][yy]=='.')
            if(left(dep+1,xx,yy,(i+dire-1+4)%4))
                return true;
    }
    return false;
}
bool right(int dep,int x,int y,int dire){
    for(int i=0;i<=3;i++){
        int xx=x+pri[(dire+2-i+4)%4][1],yy=y+pri[(dire+2-i+4)%4][2];
        if(xx<1||xx>row||yy<1||yy>columns)
            continue;
        if(chess[xx][yy]=='E'){
            printf("%d ",dep+1),flag=1;
            return true;
        }
        else if(chess[xx][yy]=='.')
            if(right(dep+1,xx,yy,(dire+2-i-1+4)%4))
                return true;
    }
    return false;
}
bool id_dfs(int dep,int x,int y,int dire){
    if(dep>maxdep)
        return false;
    if(abs(end[1]-x)+abs(end[2]-y)+dep-1>maxdep)
        return false;//一定要加剪枝,不加会TLE的很惨!!!加了0MS,你自己选吧(~~~~(>_<)~~~~)
    for(int i=0;i<=3;i++){
        int xx=x+pri[(i+dire+4)%4][1],yy=y+pri[(i+dire+4)%4][2];
        if(xx<1||xx>row||yy<1||yy>columns)
            continue;
        if(chess[xx][yy]=='E')
            return true;
        else if(chess[xx][yy]=='.')
            if(id_dfs(dep+1,xx,yy,(i+dire-1+4)%4))
                return true;
    }
    return false;
}
int main(){
    scanf("%d",&cas);
    while(cas--){
        scanf("%d%d",&columns,&row);
        for(int i=1;i<=row;i++){
            scanf("%s",str);
            for(int j=1;j<=columns;j++){
                chess[i][j]=str[j-1];
                if(chess[i][j]=='S')
                    start[1]=i,start[2]=j;
                else if(chess[i][j]=='E')
                    end[1]=i,end[2]=j;
            }
        }
        pri[0][1]=0,pri[0][2]=-1,pri[1][1]=-1,pri[1][2]=0,pri[2][1]=0,pri[2][2]=1,pri[3][1]=1,pri[3][2]=0;
        flag=0,left(1,start[1],start[2],0);
        flag=0,right(1,start[1],start[2],0);
        for(int i=1;i;i++){
            maxdep=i;
            if(id_dfs(1,start[1],start[2],0)){
                printf("%d\n",maxdep+1);
                break;
            }
        }
    }
    return 0;
} 

by >o< neighthorn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值