Gym 101147B

https://vjudge.net/problem/Gym-101147B

题意:一个人怕热,他想穿过这条街道,他想要尽可能少的晒到太阳,求最少需要晒多少太阳。

很明显是最短路。只不过问题在于构图。只要把这个图建立出来了,一个dij伙子floyd就可以解决这个问题

构图:

对于这种分布在一边的,两个矩形的距离就等于

两个矩形离起点的距离减去下面矩形的高就可以了

还有的不外乎这几种分布不在一边的,当然也还可以重合,但是重合分在第二种情况考虑

第一种,比较b的右上点和a的左下点的距离和b的左下点和a的右上点的距离,取小的便可

第二种,就是街道的宽度-a和b的宽度与0比较,大于0距离则为wi-a.wi-b.wi,否则说明二者可以重合,距离为0

第三种,则只需要考虑他们之间与起点的距离,大的减去小的便可,第三种不用和0比,因为第三种重合的话,必定为第二中情况

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <math.h>
 4 #include <iostream>
 5 #include <stdlib.h>
 6 #include <algorithm>
 7 #include <queue>
 8 #define maxn 111
 9 using namespace std;
10
11 double Dis[maxn][maxn];
12 int n,wi,len;
13
14
15 struct Rect
16 {
17     int k,di,width,len;
18 } rect[105];
19
20 double dis(Rect a,Rect b)
21 {
22     if(a.k==b.k)
23     {
24         if(a.di>b.di)
25             return a.di-(b.di+b.len)>0?a.di-(b.di+b.len):0;
26         else
27             return b.di-(a.di+a.len)>0?b.di-(a.di+a.len):0;
28     }
29     else if(a.k==1&&b.k==0)
30     {
31        if((a.di+a.len>=b.di&&a.di<=b.di)||(a.di<=b.di+b.len&&a.di>=b.di))//二者有重合部分
32             return wi-a.width-b.width>0?wi-a.width-b.width:0;
33        else if(wi-a.width-b.width<=0)
34             return a.di-(b.di+b.len)>b.di-a.di-a.len?a.di-(b.di+b.len):b.di-a.di-a.len;
35         return
36                 sqrt(1.0*(b.width-wi+a.width)*(b.width-wi+a.width)+1.0*(b.di-a.len-a.di)*(b.di-a.len-a.di))>
37                 sqrt(1.0*(b.width-wi+a.width)*(b.width-wi+a.width)+1.0*(b.di+b.len-a.di)*(b.di+b.len-a.di))?
38                 sqrt(1.0*(b.width-wi+a.width)*(b.width-wi+a.width)+1.0*(b.di+b.len-a.di)*(b.di+b.len-a.di)):
39                 sqrt(1.0*(b.width-wi+a.width)*(b.width-wi+a.width)+1.0*(b.di-a.len-a.di)*(b.di-a.len-a.di));
40     }
41     else
42     {
43         if((b.di+b.len>=a.di&&b.di<=a.di)||(b.di<=a.di+a.len&&b.di>=a.di))//二者有重合部分
44             return wi-b.width-a.width>0?wi-b.width-a.width:0;
45        else if(wi-a.width-b.width<=0)
46             return a.di-(b.di+b.len)>b.di-a.di-a.len?a.di-(b.di+b.len):b.di-a.di-a.len;
47         return
48                 sqrt(1.0*(a.width-wi+b.width)*(a.width-wi+b.width)+1.0*(a.di+a.len-b.di)*(a.di+a.len-b.di))>
49                 sqrt(1.0*(a.width-wi+b.width)*(a.width-wi+b.width)+1.0*(a.di-b.len-b.di)*(a.di-b.len-b.di))?
50                 sqrt(1.0*(a.width-wi+b.width)*(a.width-wi+b.width)+1.0*(a.di-b.len-b.di)*(a.di-b.len-b.di)):
51                 sqrt(1.0*(a.width-wi+b.width)*(a.width-wi+b.width)+1.0*(a.di+a.len-b.di)*(a.di+a.len-b.di));
52     }
53     return 0;
54 }
55
56
57
58 int main()
59 {
60     freopen("street.in","r",stdin);
61    // freopen("in.txt","r",stdin);
62     int t;
63     int a,b,c,d;
64     scanf("%d",&t);
65     while(t--)
66     {
67         scanf("%d%d%d",&n,&len,&wi);
68         for(int i = 1; i<=n; i++)
69         {
70             scanf("%d%d%d%d",&rect[i].len,&rect[i].width,&rect[i].di,&rect[i].k);
71         }
72         for(int i = 1;i<=n;i++)
73         {
74             Dis[0][i] = Dis[i][0] = rect[i].di;
75             Dis[n+1][i] = Dis[i][n+1] = len-rect[i].di-rect[i].len;
76         }
77         Dis[0][n+1] = Dis[n+1][0] = len;
78         for(int i = 1;i<=n;i++)
79         {
80             for(int j = 1;j<=n;j++)
81             {
82                Dis[i][j] = dis(rect[i],rect[j]);
83             }
84         }
85         for(int k=0;k<=n+1;k++)
86             for(int i=0;i<=n+1;i++)
87                 for(int j=0;j<=n+1;j++)
88                     Dis[i][j]=min(Dis[i][j],Dis[i][k]+Dis[k][j]);
89         printf("%.6lf\n",Dis[0][n+1]);
90     }
91     return 0;
92 }
时间: 2024-08-10 13:11:25

Gym 101147B的相关文章

【最短路】【Heap-dijkstra】Gym - 101147B - Street

按题意把图建出来跑最短路就行了.注意遮挡不会影响答案,所以不必考虑,因为走直线经过遮挡的时候,一定不会比答案更优. #include<cstdio> #include<algorithm> #include<queue> #include<cmath> #include<cstring> using namespace std; #define EPS 0.00000001 #define N 109 int T,n,H,X; int hs[N]

CodeForces Gym 100935D Enormous Carpet 快速幂取模

Enormous Carpet Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Gym 100935D Description standard input/outputStatements Ameer is an upcoming and pretty talented problem solver who loves to solve problems using computers.

B - Average Gym - 101161B 组合数学

http://codeforces.com/gym/101161/attachments 今天被卡常了,其实是自己对组合数技巧研究的不够. 如果是n, m <= 1e5的,然后取模是质数,那么可以用费马小定理. 如果n, m都比较小,那么其实是直接杨辉三角.不用逆元那些. 这题的思路是,枚举每一一个ave,然后总和就是n * ave 相当于方程  x1 + x2 + .... + xn = n * ave中,在0 <= x[i] <= full的情况下,不同解的个数中,使得x[i] ==

Codeforces Gym 100269 Dwarf Tower (最短路)

题目连接: http://codeforces.com/gym/100269/attachments Description Little Vasya is playing a new game named "Dwarf Tower". In this game there are n different items,which you can put on your dwarf character. Items are numbered from 1 to n. Vasya want

CodeForces Gym 101063C 二进制压缩

http://codeforces.com/gym/101063/problem/C 给n个人,m样物品,每个人可以从物品中选择几样.两人选择物品的交集元素个数比上并集元素个数如果大于某个比例即可将两人配对.求配对数. n的范围是1e5,直接比较所有人的选择会TLE,应该将所有选择物品的情况用二进制压缩,m最大是10,情况数目小于2048,可以接受.注意配对总数范围应为long long. #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> i

Gym 101246H ``North-East&#39;&#39;(LIS)

http://codeforces.com/gym/101246/problem/H 题意: 给出n个点的坐标,现在有一个乐队,他可以从任一点出发,但是只能往右上方走(包括右方和上方),要经过尽量多的点.输出它可能经过的点和一定会经过的点. 思路: 分析一下第一个案例,在坐标图上画出来,可以发现,他最多可以经过4个点,有两种方法可以走. 观察一下,就可以发现这道题目就是要我们求一个LIS. 首先,对输入数据排一下顺序,x小的排前,相等时则将y大的优先排前面. 用二分法求LIS,这样在d数组中就可

Gym 100712I Bahosain and Digits(开关翻转问题)

http://codeforces.com/gym/100712/attachments 题意: 给出一串数字,每次选择连续的k个数字加上任意数(超过10就取余),最后要使得所有数字都相等,求最大的k. 思路: 开关翻转问题. 算法具体可以参考<挑战程序竞赛>常用技巧篇. 这道题目就是在枚举k的同时再枚举一下最后要转换成的数字即可. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring>

很好的脑洞题:dfs+暴力 Gym - 101128A Promotions

http://codeforces.com/gym/101128 题目大意:给你一个a,b,e,p.有e个点,p条有向边,每条边为(x,y),表示x->y,每次我们都取出一个入度为0的,并且一次性取出来的个数为a(或b).当然,取出来的种类可能有很多种(即一个集合),问,这个集合中有多少个数字是相同的. 第一个输出集合长度为a的,第二个输出集合长度为b的,第三个输出无论如何都无法被取出的个数. 思路:建立正向图和反向图. 定义pair<int, int> interval[i] 表示第i

【树状数组】Gym - 101147J - Whistle&#39;s New Car

题意就是对每个点i,统计在其子树内(不含自身),且depj-depi<=xj的点有多少个. 把点分别按照dep-x和dep进行排序,离线处理, 每次把dep-x小于等于当前dep值的点插入树状数组,就变成了询问dfs序在一个区间内的点有多少个,可以用树状数组轻松解决. #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int f,C; void R(int &am