搜狗2019秋招的一道算法题:龟兔赛跑

时间限制:3秒

空间限制:92160K

定义如下图所示的比赛地图:
 
S表示比赛起点,E表示比赛终点。实线表示陆路,虚线表示水路。兔子只能走陆路,乌龟既可以走陆路也可以走水路。每条路径的长度在图中给出。假定兔子和乌龟足够聪明,问谁先到达终点。

输入描述:
第1行输入v1,v2。v1是兔子的速度,v2是乌龟的速度(水路、陆路速度相同)。第2行输入n,m,点的编号是1~n,然后是m行,其中1是起点,n是终点(路径本身不限定方向)。下面m行4个数 a, b, d, c,表示a和b之间有一条边,且其长度为d,类型是c(0表示陆路,1表示水路)。最后一行是end,表示输入结束。输入保证1和n之间至少有一条路径联通。(1<n<=10000, 0<m<=1000000)。
输出描述:
输出-1,0,1中的一个数。-1表示乌龟获胜,1表示兔子获胜,0表示同时到达终点。
输入例子1:
10 5
3 3
1 2 30 0
2 3 20 0
1 3 20 1
end
输出例子1:
-1

声明:这道题在牛客提交只过了90%的数据,拿到了45分,最后一个样例没过,思考了很久,认为都考虑到了,又看了下分数排名,我认为他们的最后一个比较大的case数据有问题。如果有人都过了case也可以留下评论,我哪里写错了。代码如下:
#include <stdio.h>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <vector>
#define INF 2100000000

using namespace std;

int n, m;
struct node
{
    int point; //端点
    int weight; //路径长度
    bool worl; //是否水路
};
vector<node>amap[10010];
unsigned int dis[10010];
bool vis[10010];

int Dijkstra(bool torr)
{
    memset(vis, false, sizeof(vis));
    for(int i=1; i<=n; i++) {
        dis[i] = INF; //代表不可达
    }
    int len = amap[1].size();

    if(torr) {
        for(int i=0; i<len; i++) {
            if( amap[1][i].weight < dis[amap[1][i].point] )
                dis[amap[1][i].point] = amap[1][i].weight;
        }
    } else {
        for(int i=0; i<len; i++) {
            if( !amap[1][i].worl && amap[1][i].weight < dis[amap[1][i].point] )
                dis[amap[1][i].point] = amap[1][i].weight;
        }
    }

    vis[1] = true;

    for(int k=0; k<n-1; k++) {
        int pos, mdis = INF;

        for(int i=1; i<=n; i++) {
            if(!vis[i] && dis[i] < mdis) {
                mdis = dis[i]; pos = i;
            }
        }
        vis[pos] = true;
        len = amap[pos].size();

        if(torr == true) { // 乌龟的话,所有的dis都可以拿来更新
            for(int j=0; j<len; j++) {
                if( !vis[amap[pos][j].point] && dis[amap[pos][j].point] > (amap[pos][j].weight+dis[pos]) ) {
                    dis[ amap[pos][j].point ] = amap[pos][j].weight + dis[pos];
                }
            }
        } else { // 兔子的话,更新的可选路径必须是陆路
            for(int j=0; j<len ; j++) {
                if( !vis[amap[pos][j].point] && !amap[pos][j].worl && dis[amap[pos][j].point] > (amap[pos][j].weight+dis[pos]) )
                    dis[ amap[pos][j].point ] = amap[pos][j].weight + dis[pos];
            }
        }
    }
    return dis[n];
}

int main()
{
    double vt, vg;
    scanf("%lf %lf", &vt, &vg);
    scanf("%d %d", &n, &m);

    int a, b, c, d;
    node cur;
    for(int i=0; i<m; i++) {
        scanf("%d %d %d %d", &a, &b, &c, &d);
        cur.point = b;
        cur.weight = c;
        cur.worl = (d==1?true:false);
        amap[a].push_back(cur);
    }
    char str[100];
    scanf("%s", str);

    double tt = (double)Dijkstra(false) / vt; // tu zi
    double tg = (double)Dijkstra(true) / vg; // gui

    double eps = 1e-8;
    if(fabs(tt - tg) < eps) {
        printf("0\n");
    } else if(tt - tg > eps) {
        printf("-1\n");
    } else {
        printf("1\n");
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/yspworld/p/10527435.html

时间: 2024-08-02 17:30:18

搜狗2019秋招的一道算法题:龟兔赛跑的相关文章

2015阿里秋招其中一个算法题(经典)

写一个函数,输入一个二叉树,树中每个节点存放了一个整数值,函数返回这棵二叉树中相差最大的两个节点间的差值绝对值.请注意程序效率 这是2015阿里秋招的一个在线笔试题 实现方法很简单,遍历一遍二叉树,找出最大最小,一相减就可以求出最大的差值 之前在做题的时候居然写递归的方法求值,后面测试了一下,果然结果不对 只要是非递归的的方法遍历都可以很容易找出最大值最小值,效率也比较高,时间复杂度为O(n). 下面是我用非递归从上往下遍历二叉树的方法 用队列容器即可方便实现. 我写的代码: #include

美团2019秋招后台开发编程题题解

图的遍历 题目描述 给定一张包含N个点.N-1条边的无向连通图,节点从1到N编号,每条边的长度均为1.假设你从1号节点出发并打算遍历所有节点,那么总路程至少是多少? 输入 第一行包含一个整数N,1≤N≤105. 接下来N-1行,每行包含两个整数X和Y,表示X号节点和Y号节点之间有一条边,1≤X,Y≤N. 输出 输出总路程的最小值. 样例输入 4 1 2 1 3 3 4 样例输出 4 Hint 按1->2->1->3->4的路线遍历所有节点,总路程为4. 思路 遍历所有节点类似于深度

一天一道算法题---6.26---二分查找

感谢微信平台---一天一道算法题----每天多一点进步-- 好累啊  现在在用win7自带的输入法 打起来真麻烦 快点把这2天的搞完就重装了 还是直接来源于----〉 待字闺中 分析 给定一个数组A,其中有一个位置被称为Magic Index,含义是:如果i是Magic Index,则A[i] = i.假设A中的元素递增有序.且不重复,请给出方法,找到这个Magic Index.更进一步,当A中允许有重复的元素,该怎么办呢? 没有重复元素的情况 一些同学在遇到这个题目的时候,往往会觉得比较简单.

一天一道算法题--6.25--无定义

感谢微信平台---一天一道算法题--每天多一点进步---- 其实今天我接下去补上的几题都来自---待字闺中 所以我就原封不动的将它的题目与分析搬过来了 原题 给定一个数组,我们可以找到两个不相交的.并且是连续的子数组A和B,A中的数字和为sum(A), B中的元素和为sum(B).找到这样的A和B,满足sum(A) - sum(B)的绝对值是最大的. 例如:[2, -1 -2, 1, -4, 2, 8]划分为A=[-1, -2, 1, -4], B=[2, 8], 最大的值为16 分析 如果没有

一天一道算法题---6.27---二分图

感谢微信平台---一天一道算法题---每天多一点进步--- Ah... last... 也很晚了 快2点半了 C罗也告别这届世界杯了  主要还是输给德国太多球了 美国也没赢 唉 还是来源于----> 待字闺中 原题 大家都知道facebook用户都是双向的好友,a是b的好友,那么b一定是a的好友,现在给定一个用户列表,其中有些用户是好友,有些不是,请判断,这些用户是否可以划分为两组,并且每组内的用户,互相都不是好友.如果能,请给出这个划分. 例子1: 用户:{1, 2, 3} 好友关系:1-2,

前端面试的一道算法题

(使用canvas解答) 下面说一个跟前端有点相关并且有点趣的一道算法题. 题目: 平面上有若干个不特定的形状,如下图所示.请写程序求出物体的个数,以及每个不同物体的面积. 分析 想要知道有多少个图形,想到的就是先获取图片中的每一个像素点然后判获取像素点的背景颜色(RGBA).想要获得图片中的每一个像素点,那就可以联想到使用h5的canvas.如下: 菜鸟教程中canvas的getimagedata方法http://www.runoob.com/tags/canvas-getimagedata.

一天一道算法题--6.19--二分搜索

感谢微信平台---一天一道算法题---每天多一点进步 这是昨天的 只贴下题目 == 再把今天的也是一样处理了   这2天 不想写 可能晚上会有改变吧.. problem: 给定一个最多包含40亿个随机排列的32位 二进制的无符号整数 找出不在文件中的数.显然 由于 2^32=4294967196大于4亿 所以缺少的数不止一个 现限制只能使用几个外部的临时文件和仅几百个字节的内存. ****************************** 过了明天 就没事了 =-= 一天一道算法题--6.19

一天一道算法题--6.13---计算几何

感谢微信平台---一天一道算法题---每天多一点进步 本来 想在世界杯之前 可以 开开心心地A了今天的算法题  .... 竟然是计算几何 我高数 那么渣....... 这题 先放着吧..... 哎.... 链接 还是一样先放出来 . touch me 平常这个点 再过会 就应该要碎觉了 今天 = 个揭幕战 累死我的节奏,,, 现在去做点什么呢........... 一天一道算法题--6.13---计算几何,布布扣,bubuko.com

一天一道算法题--5.29---动态规划之数塔

感谢微信平台:  一天一道算法题-------每天多一点进步----------- 这题的话 我就直接用我们自己Oj的题目了 戳我 好吧  如今看这题  是很简单  当时 是块被它搞崩溃了   因为 还不知道  dp 这个概念 现在有了这个概念   好多了  但还是 只能做做这种水 dp.... 多么悲伤的故事 这题 因为太水了   晚上 应该会去找个高质量的题来做的 如果你是dp刚刚学 这题真的很适合你 1 #include <iostream> 2 #include <cstring