UVA - 1001 Say Cheese(奶酪里的老鼠)(flod)

题意:无限大的奶酪里有n(0<=n<=100)个球形的洞。你的任务是帮助小老鼠A用最短的时间到达小老鼠O所在位置。奶酪里的移动速度为10秒一个单位,但是在洞里可以瞬间移动。洞和洞可以相交。输入n个球的位置和半径,以及A和O的坐标,求最短时间。

分析:

1、因为洞可以相交,所以在计算两点距离时要判断一下if(dist > num[i].r + num[j].r)。

2、两球间的距离为球心间距离-两球半径,起点和终点不是球,可将半径设为0。

#pragma comment(linker, "/STACK:102400000, 102400000")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define Min(a, b) ((a < b) ? a : b)
#define Max(a, b) ((a < b) ? b : a)
const double eps = 1e-8;
inline int dcmp(double a, double b){
    if(fabs(a - b) < eps) return 0;
    return a > b ? 1 : -1;
}
typedef long long LL;
typedef unsigned long long ULL;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
const int MOD = 1e9 + 7;
const double pi = acos(-1.0);
const int MAXN = 100 + 10;
const int MAXT = 10000 + 10;
using namespace std;
double d[MAXN][MAXN];
struct Point{
    int x, y, z, r;
    void read(){
        scanf("%d%d%d", &x, &y, &z);
    }
}num[MAXN];
double getD(Point &A, Point &B){
    return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y) + (A.z - B.z) * (A.z - B.z));
}
int main(){
    int n;
    int kase = 0;
    while(scanf("%d", &n) == 1){
        if(n == -1) return 0;
        memset(d, 0, sizeof d);
        for(int i = 0; i < n; ++i){
            num[i].read();
            scanf("%d", &num[i].r);
        }
        num[n].read(), num[n].r = 0;
        num[n + 1].read(), num[n + 1].r = 0;
        for(int i = 0; i < n + 2; ++i){
            for(int j = i + 1; j < n + 2; ++j){
                double dist = getD(num[i], num[j]);
                if(dist > num[i].r + num[j].r){
                    d[i][j] = d[j][i] = dist - num[i].r - num[j].r;
                }
                else{
                    d[i][j] = d[j][i] = 0;
                }
            }
        }
        for(int k = 0; k < n + 2; ++k){
            for(int i = 0; i < n + 2; ++i){
                for(int j = 0; j < n + 2; ++j){
                    d[i][j] = Min(d[i][j], d[i][k] + d[k][j]);
                }
            }
        }
        printf("Cheese %d: Travel time = %.0lf sec\n", ++kase, d[n][n + 1] * 10);
    }
    return 0;
}

  

时间: 2024-10-05 21:44:27

UVA - 1001 Say Cheese(奶酪里的老鼠)(flod)的相关文章

UVa 1001 奶酪里的老鼠(Dijkstra或Floyd)

https://vjudge.net/problem/UVA-1001 题意:一个奶酪里有n个洞,老鼠在奶酪里的移动速度为10秒一个单位,但是在洞里可以瞬间移动.计算出老鼠从A点到达O点所需的最短时间. 思路:最短路问题. 我们可以把起点和终点也看成是两个洞,半径为0.这样每个洞就代表了一个点,对于两个洞而言,圆心距离大于两半径之和,此时它们之间的距离就为圆心距离-两半径之和,否则就为0. 我们在计算出任意两个洞之间的距离之后,就可以套用最短路代码来解题了.下面的代码我是用了Floyd算法. 1

UVa 1001 Say Cheese (Dijkstra)

题意:给定一个三维空间的一些球和起始位置和结束位置,问你最短要花的时间是多少. 析:建图,所有的位置都建立图,边权就是距离,最小求一次最短路即可. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <

UVA 1001 Say Cheese

题意: 一只母老鼠想要找到她的玩具,而玩具就丢在一个广阔的3维空间上某个点,而母老鼠在另一个点,她可以直接走到达玩具的位置,但是耗时是所走过的欧几里得距离*10s.还有一种方法,就是靠钻洞,洞是球形的,在洞内怎么走都是不耗时间的.求母老鼠找到她的玩具所耗时? 分析: 洞到洞的最短距离都是圆心距离减去半径.剩下的就是求单源最短路径. 代码: #include <iostream>#include <cstring>#include <cstdio>#include <

UVA 1001 Say Cheese (最短路,floyd)

题意:一只母老鼠想要找到她的公老鼠玩具(cqww?),而玩具就丢在一个广阔的3维空间(其实可以想象成平面)上某个点,而母老鼠在另一个点,她可以直接走到达玩具的位置,但是耗时是所走过的欧几里得距离*10s.还有一种方法,就是靠钻洞,洞是球的,而在洞内怎么走都是不耗时间的.求母老鼠找到她的玩具所耗时? 思路:先要看清楚题意先!尽可能要找到洞,如果洞的半径越大,那么就可以越省时.如果老鼠和玩具都在同个洞上,那么不耗时即可找到. 其实就是求单源最短路,只是计算两点间的长度时要考虑到半径的.而且得注意两洞

uva 10090 - Marbles(欧几里得+通解)

题目链接:uva 10090 - Marbles 题目大意:给出n,表示有n个珠子,现在要用若干个盒子来装.有两种盒子,一种价钱c1,可以装t1个珠子,另一种价钱c2,可以装t2个珠子.要求所卖的盒子刚好装n个珠子,并且价钱最小的方案. 解题思路:用拓展欧几里得算法求出xt1+yt2=n的一对解x′和y′,这样就有通解: x=x′ngcd(t1,t2)+t2gcd(t1,t2)k y=y′ngcd(t1,t2)?t1gcd(t1,t2)k 然后根据性价比选择一种盒子的个数尽量多. #includ

uva 1001(最短路)

题意:在一个三维的奶酪里面有n(n<=100)个洞,老鼠A想到达老鼠B的位置,在洞里面可以瞬间移动,在洞外面的移动速度为10秒一个单位,求最短时间 题解:如果两个洞相交,那么d[i][j]=0:如果不相交,那么d[i][j]=dist-(r[i]+r[j]),dist为这两个洞圆心之间的欧几里得距离 再用Dijkstra处理就可以了 #include <cstdio> #include <iostream> #include <sstream> #include

uva 1001 建图+最短路

题意: 在一个三维的空间内求从起点到终点的最短时间花费. 其中n个洞,在洞内通过的时间花费是0,在洞外的时间花费是每单位10sec 思路: 水题 建立起点到每个洞的边,建立终点到每个洞的边,建立起点到终点的边 ,边权是到达所需的时间花费.求一次最短路即可. code: #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #i

1001 - Say Cheese (Dijkstra算法)

该题是求两点间的最短路问题,用Dijkstra算法比较快 ,跑了0.003s . 方法很简单,将圆看成结点,直接判断两个圆是否相交,如果相交距离为0,否则距离为圆心间距离减去两圆半径. 起点和终点也可以看成是一个半径为0的圆 . 这样就变成了两点间的最短路问题,适合用Dijkstra算法求解.  比较坑的是该题说了数据范围n最大100,但是我开了105竟然RE ,看成505就过了 .  所以在占用内存不多的情况下还是开大一点好 . 细节参见代码: #include<bits/stdc++.h>

[HDU 1078]FatMouse and Cheese(记忆化DFS)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1078 题目大意:一个胖老鼠要在一个n*n大小的棋盘里吃奶酪,这个老鼠每一步最多能走k单位远,而且每走一步,必须走到比当前点奶酪数多的点那去.告诉你这个棋盘里每个点上的奶酪个数,求这个老鼠最多能吃多少奶酪. 思路:类似于棋盘DP的记忆化DFS,直接搜加记忆答案就可以了. #include <iostream> #include <stdio.h> #include <string.