zoukankan      html  css  js  c++  java
  • hdu

    这道题因为某些位置要重复走,所以不能用标记的方法,但是为了提高效率,可以采用time[]数组和step[]数组来剪枝,很容易想到,当你从一条路劲走到(x,y)处的时间和步骤

    比从另一条路劲走到(x,y)处的时间和步骤小时,那么time[]数组和step[]数组将这个最小的时间和步骤记录下来,即time[]和step[]记录的是到达每个位置用的最小的时间和步骤,如果当你从某一条路径到达(x,y)处的时间和步骤大于已记录值时,直接返回而不继续走下去。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <climits>
    
    
    const int MAX = 9;
    
    int dir[4][2]={1,0,-1,0,0,1,0,-1};
    
    int map[MAX][MAX],step[MAX][MAX],time[MAX][MAX];
    int n,m,sx,sy,dx,dy,minx;
    
    void dfs(int x,int y,int len,int cnt){
        if(x<0 || y<0 || x>=n || y>=m)return;
        if(len<=0 || cnt>=minx)return;
        if(map[x][y]==0)return;
        if(map[x][y]==3){
            if(cnt<minx)minx=cnt;
            return;
        }
        if(map[x][y]==4){
            len=6;
        }
        //下面的这个剪枝很重要,不剪就会超时
        //从当前点x,y走到下一个可能点的距离大于从其他途径到tx,ty的距离,且到tx,ty点时的剩余时间大于由x,y点到tx,ty点后的剩余时间,就跳过
        //这是因为结点可重复访问所以本身没标记,那么当上述条件满足时,由tx,ty开始的最优解已经求过(存在或者不存在),所以不需要再重复求了。
        if(cnt>=step[x][y] && time[x][y]>=len)return;
        step[x][y]=cnt;
        time[x][y]=len;
        int tx,ty,i;
        for(i=0;i<4;++i){
            tx = x+dir[i][0];
            ty = y+dir[i][1];
            dfs(tx,ty,len-1,cnt+1);
        }
    }
    
    int main(){
    
        //freopen("in.txt","r",stdin);
        int t,i,j,len,cnt;
        scanf("%d",&t);
        while(t--){
            scanf("%d %d",&n,&m);
            for(i=0;i<n;++i){
                for(j=0;j<m;++j){
                    time[i][j]=0;
                    step[i][j]=INT_MAX-3;//这里置一个大数,表示到i,j的步数无限大
                    scanf("%d",&map[i][j]);
                    if(map[i][j]==2){
                        sx = i;
                        sy = j;
                    }else if(map[i][j]==3){
                        dx = i;
                        dy = j;
                    }
                }
            }
            len = 6;
            cnt = 0;
            minx = INT_MAX;
            dfs(sx,sy,len,cnt);
            if(minx==INT_MAX){
                printf("-1
    ");
            }else{
                printf("%d
    ",minx);
            }
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    万恶的 one or more listeners failed to start 和 Servlet.init() for servlet [dispatcherServlet] threw exception
    实验四 主存空间的分配和回收
    实验二 作业调度模拟程序
    实验一
    实验三
    【安卓】实验7 BindService模拟通信
    计时器页面设计
    实验五 存储管理实验
    实验6 在应用程序中播放音频和视频
    实验5数独游戏界面设计
  • 原文地址:https://www.cnblogs.com/acm-jing/p/4369978.html
Copyright © 2011-2022 走看看