hrbust/哈理工oj 1617 回家【BFS+BFS】


回家


Time Limit: 1000 MS


Memory Limit: 32768 K


Total Submit: 35(9 users)


Total Accepted: 10(8 users)


Rating:


Special Judge: No


Description


寒假里,大家经常会遇上同学聚会,ikki也不例外。

ikki所在的城市可以看成是一个正方形的布局,分为n*n个小方格区域。ikki每次聚会的场所都在城市的西北角,即方格

(1,1)表示的位置,而家位于城市的东南角,即(n,n)表示的位置。由于有很多条路线可以选择,ikki希望每次回家的路线

都不相同,并且ikki希望自己每经过一个区域之后,离家更近一些,具体而言:假如ikki要从A区域到B区域,那么必须满足

从B区域到家需要花的最少时间要比从A区域到家花的最少时间要少。现在ikki想知道有多少条不同的回家路线。


Input


每组数据第一行为一个整数n(2<=n<=50),接下来的n行,每行有n个整数(1<=m<=50),分别表示经过该区域所需要花的时间,注意起点和终点区域也需要花时间。


Output


对于每组数据输出不同的路线的总数(小于2^63)。


Sample Input


3

1 1 1

1 1 1

1 1 1

3

1 2 3

1 2 3

1 2 3


Sample Output


6

1


Author


周洲@hrbust

为什么中文题还要说中问题意呢。因为这个题容易理解错误。

题目大意:从一个点到另一个点能走的前提是:当前点到终点的距离,大于想要走的点到终点的距离,才行。

思路:既然是要有刚刚说的那样一个限制条件下,我们才能向前走,辣么不用多想,先逆向思维,求终点到其他所有点的最小距离。这样我们就有了所有点到终点的距离。然后再写一遍BFS,累加能够走的情况数,即可。

AC代码:

#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
#define ll long long
struct zuobiao
{
    int x,y,output;
    friend bool operator <(zuobiao a,zuobiao b)
    {
        return a.output>b.output;
    }
}now,nex;
int n;
int a[55][55];
int dis[55][55];
int vis[55][55];
ll ans[55][55];
int fx[4]={0,0,1,-1};
int fy[4]={1,-1,0,0};
void bfs(int x,int y)
{
    memset(dis,0,sizeof(dis));
    now.x=x;
    now.y=y;
    now.output=a[x][y];
    priority_queue<zuobiao>s;
    dis[x][y]=a[x][y];
    s.push(now);
    while(!s.empty())
    {
        now=s.top();
        s.pop();
        for(int i=0;i<4;i++)
        {
            nex.x=now.x+fx[i];
            nex.y=now.y+fy[i];
            if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<n&&dis[nex.x][nex.y]==0)
            {
                dis[nex.x][nex.y]=dis[now.x][now.y]+a[nex.x][nex.y];
                nex.output=dis[nex.x][nex.y];
                s.push(nex);
            }
        }
    }
}
void bfs2(int x,int y)
{
    memset(vis,0,sizeof(vis));
    memset(ans,0,sizeof(ans));
    priority_queue<zuobiao>s;
    now.x=x;
    now.y=y;
    now.output=dis[x][y];
    s.push(now);
    vis[x][y]=1;
    ans[x][y]=1;
    while(!s.empty())
    {
        now=s.top();
        s.pop();
        for(int i=0;i<4;i++)
        {
            nex.x=now.x+fx[i];
            nex.y=now.y+fy[i];
            nex.output=dis[nex.x][nex.y];
            if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<n)
            {
                if(dis[nex.x][nex.y]>now.output)
                {
                    ans[nex.x][nex.y]+=ans[now.x][now.y];
                    if(vis[nex.x][nex.y])continue;
                    vis[nex.x][nex.y]=1;
                    s.push(nex);
                }
            }
        }
    }
    printf("%lld\n",ans[0][0]);
}
int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                scanf("%d",&a[i][j]);
            }
        }
        bfs(n-1,n-1);
        bfs2(n-1,n-1);
    }
    return 0;
}
时间: 2024-08-11 07:41:49

hrbust/哈理工oj 1617 回家【BFS+BFS】的相关文章

hrbust/哈理工oj 1677 一个函数【栈】【水题】

一个函数 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 49(38 users) Total Accepted: 39(36 users) Rating:  Special Judge: No Description 现在用一个函数来处理一个字符串(该字符串只包含x和y). 函数的两个操作如下. 1.  在字符串中找到两个连续的字符(可以不相邻),并且第一个字符是'y',第二个字符是'x',然后交换它们.如果一次存在多种满足该条件

hrbust/哈理工oj 1334 最好的心情【求最长递增子序列&amp;&amp;最大值】

最好的心情 Time Limit: 1000 MS Memory Limit: 65536 K Total Submit: 200(44 users) Total Accepted: 55(38 users) Rating: Special Judge: No Description 俗话说"月有阴晴圆缺,人有悲欢离合.". 虽然大家都没这么悲催,但是心情的波动在所难免. MM的心情也会有波动,心情好心情值就高,心情不好心情值就低,每个小时都不一样,GG想知道MM最长的上升心情值的子序

hdu1254 推箱子 搜索水题(bfs+bfs)

题意就不多说了 我使用bfs+bfs做的      听说bfs+dfs也能做   我觉得都差不多     我就说一下bfs+bfs 注意:箱子走过的地方还能再走   但从同一方向过来的就不能再走了    所以  标记时  得同时记录箱子和方向    方向可以根据人的位置来判断 箱子能往某一方向推的两个条件是: 目的地是空的    人能推动及人能到达要推的地方 然后按照一般广搜做就行 #include<stdio.h> #include<string.h> #include<q

hdu1254推箱子 (BFS+BFS+状态压缩)

推箱子 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5089 Accepted Submission(s): 1421 Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子,因此如果箱

二叉树的建立与遍历(山东理工OJ)

数据结构实验之二叉树的建立与遍历 题目描述 已知一个按先序序列输入的字符序列,如abc,,de,g,,f,,,(其中逗号表示空节点).请建立二叉树并按中序和后序方式遍历二叉树,最后求出叶子节点个数和二叉树深度. 输入 输入一个长度小于50个字符的字符串. 输出 输出共有4行: 第1行输出中序遍历序列: 第2行输出后序遍历序列: 第3行输出叶子节点个数: 第4行输出二叉树深度. 示例输入 abc,,de,g,,f,,, 示例输出 cbegdfa cgefdba 3 5 #include <iost

Light OJ 1141--BFS--(隐蔽的BFS)

题意:求数字A变换到B 的最小步数.变换方法是每次加A的素因数 分析:BFS 代码: #include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; int s,t,n,vis[1009],prim[1009],fac[1009]; struct h{ int x,tot; }; queue<h> q; int cnt; void

[Swust OJ 85]--单向公路(BFS)

题目链接:http://acm.swust.edu.cn/problem/0085/ Time limit(ms): 5000 Memory limit(kb): 65535 Description 某个地区有许多城镇,但并不是每个城镇都跟其他城镇有公路连接,且有公路的并不都能双向行驶.现在我们把这些城镇间的公路分布及允许的行驶方向告诉你,你需要编程解决通过公路是否可以从一个城镇到达另一个城镇.(我们规定,城镇自己跟自己可互相到达,即A可到达A). Input 第一行只有一个数N,下面将跟着2N

Pku oj 3026 Borg Maze(BFS+MST)

Borg Maze Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12028   Accepted: 3930 Description The Borg is an immensely powerful race of enhanced humanoids from the delta quadrant of the galaxy. The Borg collective is the term used to desc

hdu 1226 BFS + bfs记录路径

http://acm.hdu.edu.cn/showproblem.php?pid=1226 为了省空间,可以用vis数组初始化的时候初始化为-1, 发现一个BFS容易错的地方 开始一直WA在这里:就是我int tp=q.front();之后马上q.pop():了,然后才去判断是不是符合条件以break,这样就不能根据q.empty()==1认为没有找到ans 因为这里WA了 其实也可以vis[0] == -1来判断 比较不理解的是 当n==0的时候 %n==0的时候怎么处理 //#pragma