I.散步

Description


⑨每天吃完晚饭后都会从家出发到雾之湖及其周围去散步下,最终到达魔法森林的入口,并且尽可能尝试不同的路径。雾之湖及其周围可以抽象为一个矩形,划分为 n*m 块区域,⑨家为 (1,1) ,散步时⑨在某个区域会逗留一段时间,然后移动到东西南北相邻的其中一个格子 ( 移动时间忽略不计 ) ,经过若干次移动最终到达魔法森林 (n,m) 。因为是散步,所以起点和终点⑨都会逗留一段时间。⑨表示虽然是闲逛,但是也不能太浪费时间,还是得去终点 (n,m) 的,所以只有至少存在一条从 B 到终点的时间比从 A 到终点的所有路径所花费的时间更少时才可以从 A B 。现在⑨想知道自己一共有多少种路径可以选择,因为⑨的智商只有⑨,她自己肯定没法算出来啦。你能帮帮⑨吗?



Input


本体有多组数据。每组数据第一行为 n,m(2<=n,m<=50)  接下来为 n m 列的矩阵,表示在每个区域⑨逗留的时间t( 0<=t<=1000 )。


Output


每组数据输出一行,表示路径总数(保证小于 2^63 )。


Sample Input


3 3
1 2 3
1 2 3
1 2 3
3 3
1 1 1
1 1 1
1 1 1

Sample Output


1
6

Source


2013 Anhui College Student Programming Contest--Hu Yue

#include<iostream>
#include<cstring>
#include<queue> 
using namespace std;
int map[51][51];
int t[51][51];//t为花费 
long long s[51][51];
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int n,m;
struct pp{
    int x,y;
};
queue<pp> que;
int flag[100][100];
void bfs()//广搜 计算各个点到 (n,m)的最短距离 
{
    pp a,b;
    int dx,dy,i,spend;
    a.x=n-1;
    a.y=m-1;
    t[n-1][m-1]=map[n-1][m-1];
    que.push(a);
    while(!que.empty())
    {
        b=que.front();
        que.pop();
        for(int i=0;i<4;i++)
        {
            dx=b.x+dir[i][0];
            dy=b.y+dir[i][1];
            if(dx>=0&&dx<n&dy>=0&&dy<m)
            {
                spend=t[b.x][b.y]+map[dx][dy];
                if(t[dx][dy]==-1||spend<t[dx][dy])
                {
                    a.x=dx;
                    a.y=dy;
                    t[dx][dy]=spend;
                    que.push(a);
                }
            }
        }
     } 
}
long long dfs(int x,int y)//深搜 统计路径个数 
{
    int i;
    if(s[x][y]>-1)
        return s[x][y];
    if(x==n-1&&y==m-1)
        return 1;    
    s[x][y]=0;
    for(i=0;i<4;i++)
    {
        int xx=x+dir[i][0];
        int yy=y+dir[i][1];
        if(xx>=0&&xx<n&&yy>=0&&yy<m)
        {
            if(t[x][y]>t[xx][yy])//如果当前结点到终点的距离大于 下个个结点到终点的距离 
            {//说明这个结点还有价值 继续深搜
                s[x][y]+=dfs(xx,yy);
            
            }
        }
    }
    return s[x][y];
}
int main()
{
    int i,j;
    while(cin>>n>>m)
    {
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                cin>>map[i][j];
                t[i][j]=-1;
            }
        }
        while(!que.empty()) que.pop();//出队 
        memset(s,-1,sizeof(s));
        bfs();
       
        dfs(0,0);
       
        cout<<s[0][0]<<endl;
    }
    return 0;
 } 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值