【深基7.例1】距离函数

题目描述

给出平面坐标上不在一条直线上三个点坐标 (x1​,y1​),(x2​,y2​),(x3​,y3)(x_1​,y_1​),(x_2​,y_2​),(x_3​,y_3)(x1,y1),(x2,y2),(x3,y3),坐标值是实数,且绝对值不超过 100.00,求围成的三角形周长。保留两位小数。

对于平面上的两个点 (x1​,y1​),(x2​,y2​)(x_1​,y_1​),(x_2​,y_2​)(x1,y1),(x2,y2),则这两个点之间的距离 dis=(x2​−x1​)2+(y2​−y1​)22dis=\sqrt{(x_2​−x_1​)^2+(y_2​−y_1​)2^2}dis=(x2x1)2+(y2y1)22

输入格式

输入三行,第 iii 行表示坐标 (xi​,yi​)(x_i​,y_i​)(xi,yi),以一个空格隔开。

输出格式

输出一个两位小数,表示由这三个坐标围成的三角形的周长。

输入数据 1

0 0
0 3
4 0

输出数据 1

12.00

提示

数据保证,坐标均为实数且绝对值不超过 100100100,小数点后最多仅有 333 位。

代码

#include<bits/stdc++.h>
using namespace std;
double dis(double x1, double x2, double y1, double y2){
	return sqrt((x1 - x2) * (x1 - x2) + (y2 - y1) * (y2 - y1));
}
int main() {
	double x1, y1, x2, y2, x3, y3, s1, s2, s3;
	cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
	s1 = dis(x1, x2, y1, y2);
	s2 = dis(x3, x2, y2, y3);
	s3 = dis(x1, x3, y3, y1);
	printf("%.2lf", s1 + s2 + s3);
	return 0;
}
<think>题目要求:计算在不迟到的情况下,yyy最晚的出门时间。学校8:00到达,路上要花时间走路(s/v分钟)加上10分钟垃圾分类。注意,由于速度是整数,但时间可能是小数,需要向上取整(因为不足一分钟也要算一分钟)。 步骤: 1. 计算总共需要的时间(分钟):t = ceil(s/v) + 10 (注意:ceil(s/v)表示向上取整,因为即使多出一秒也要算一分钟) 2. 从8:00往前推t分钟,就是最晚出发时间。 3. 注意:可能跨天(提前一天出发),但题目说提前的时间不会超过一天,所以我们只需要考虑24小时内。 具体计算: 8:00相当于从00:00开始的480分钟(因为8*60=480)。 那么最晚出发时间在00:00之前的分钟数 = 480 - t(如果480-t是负数,则加上24*60,表示前一天的时间) 但是,由于t可能大于480,那么480-t为负,我们就需要加上24*60(即1440分钟)变成前一天的时间。 另一种思路:我们可以计算从一天的开始(00:00)到出发时间所经过的时间(分钟)为: 出发时间分钟数 = (480 - t + 1440) % 1440 (这样,如果480-t是负数,加上1440再取模1440,就得到前一天的时间,但题目要求输出24小时制,所以这样处理可以) 但是注意:题目要求输出格式为HH:MM,且必须两位,不足补0。 步骤: 1. 计算总时间t_total = ceil(s/v) + 10 2. 计算从8:00(480分钟)往前推t_total分钟,即出发时间分钟数 = (480 - t_total) % 1440 但是,直接减可能是负数,所以我们可以用模运算处理负数: 出发时间分钟数 = (480 - t_total + 1440) % 1440 这样,如果480-t_total是负数,加上1440后变成正数,然后模1440相当于得到前一天对应的时间(在0~1439之间)。 3. 然后,小时 = 出发时间分钟数 / 60 (整数除法),分钟 = 出发时间分钟数 % 60 4. 格式化输出:小时和分钟都要两位,不足两位前面补0。 但是注意:向上取整的方法:如果s能被v整除,那么s/v就是整数,否则需要向上取整。在C++中,我们可以这样计算: int t_walk = (s + v - 1) / v; // 这样计算向上取整,但注意当s=0时,v>=1,所以s=0时,t_walk=0,但题目s>=1,所以不用考虑0。 但是注意:题目中s和v是正整数,所以s>=1, v>=1。 因此,总时间t_total = t_walk + 10; 然后计算出发时间分钟数:total_minutes = (480 - t_total + 1440) % 1440; 解释:加上1440是为了避免负数,模1440是为了将时间限制在0~1439分钟(即24小时内)。 然后: int hour = total_minutes / 60; int minute = total_minutes % 60; 输出时,用printf("%02d:%02d", hour, minute) 或 cout << setfill(&#39;0&#39;) << setw(2) << hour << ":" << setw(2) << minute; 但是注意:如果计算出来的出发时间分钟数是0,那么就是00:00,如果小时是7,分钟是5,那么输出07:05。 示:输入100 99 s=100, v=99 t_walk = ceil(100/99) = ceil(1.01) = 2(注意:100/99=1.01,向上取整为2?不对,应该是2分钟吗?实际上,1.01分钟,但题目要求以分钟计,而且必须完整的一分钟,所以1.01分钟需要2分钟(因为第一分钟走了99米,第二分钟才走完剩下的1米)) 所以t_walk = (100+99-1)/99 = 198/99=2 (整数除法,向上取整的公式:(s+v-1)/v 就是向上取整) 总时间t_total = 2+10=12分钟 那么从8:00往前推12分钟,就是7:48。但是计算: 480 - 12 = 468分钟 -> 468/60=7小时,468%60=48分钟 -> 07:48 但是,如果t_total大于480,比如500分钟,那么480-500=-20,然后加上1440等于1420,再模1440还是1420分钟,1420分钟=23小时40分钟(1420/60=23, 1420%60=40),所以是23:40(即前一天23:40出发)。这符合题目要求(提前时间不超过一天)。 因此,代码实现如下: 注意:因为题目要求必须输出两位,所以用printf("%02d:%02d", hour, minute)比较方便。 但是,有一个边界:比如8:00到达,如果t_total=0,那么出发时间就是8:00,但这样会迟到吗?题目要求不迟到,所以应该提前出发。但是t_total至少是10分钟(垃圾分类10分钟),所以不会为0。 另外,考虑s=0的情况?题目中s>=1,所以不用考虑。 代码: ```cpp #include <iostream> #include <cstdio> #include <cmath> using namespace std; int main() { int s, v; cin >> s >> v; // 计算行走时间(向上取整) int t_walk = (s + v - 1) / v; // 因为s和v是整数,使用整数除法向上取整的技巧 int t_total = t_walk + 10; // 加上垃圾分类的10分钟 // 计算从00:00到8:00的总分钟数为480 // 出发时间在00:00之后的分钟数 = (480 - t_total + 1440) % 1440 int total_minutes = (480 - t_total + 1440) % 1440; int hour = total_minutes / 60; int minute = total_minutes % 60; // 输出两位,不足补0 printf("%02d:%02d", hour, minute); return 0; } ``` 但是,注意:上面的取模运算,当480-t_total为正数时,加上1440再模1440等于原数;当为负数时,相当于加上1440然后模1440,得到的就是前一天的时间(在0~1439之间)。 然而,我们也可以这样写:因为480-t_total最小可能是负数(最大可能是480),所以我们可以先加上1440再取模,这样保证非负。 但是,我们也可以这样: total_minutes = (1440 + 480 - t_total) % 1440; 因为1440+480是正数,减去t_total后,如果结果大于1440,取模会回到0~1439;如果小于0,加上1440再取模?不对,这里不会小于0,因为1440+480=1920,减去t_total(最大为10000/1+10=10010,但题目s,v<=10000,所以t_total最大为10000+10=10010,那么1920-10010是负数,负数取模?在C++中,负数的模运算结果可能是负数,所以我们需要调整。 因此,为了避免负数模运算的问题,我们使用: total_minutes = (480 - t_total + 1440 * 2) % 1440; 这样保证括号内为正数,然后模1440。但实际上,我们只需要加一次1440,然后模1440,因为模运算的性质: (a + b) % m = (a % m + b % m) % m,但这里我们是为了让负数变成正数,所以加一个1440的倍数使得非负。 更通用的做法:先取模,再调整到非负。 total_minutes = (480 - t_total) % 1440; if (total_minutes < 0) total_minutes += 1440; 这样更清晰。 因此,修改代码: ```cpp #include <iostream> #include <cstdio> using namespace std; int main() { int s, v; cin >> s >> v; // 计算行走时间(向上取整) int t_walk = (s + v - 1) / v; int t_total = t_walk + 10; // 计算从00:00到8:00的总分钟数为480 int total_minutes = 480 - t_total; // 可能是负数 total_minutes %= 1440; // 取模,但可能还是负数 if (total_minutes < 0) total_minutes += 1440; // 调整到0~1439 int hour = total_minutes / 60; int minute = total_minutes % 60; printf("%02d:%02d", hour, minute); return 0; } ``` 这个版本更清晰,避免了负数模运算的问题。 测试:输入100 99 -> t_walk=2, t_total=12, total_minutes=480-12=468 -> 468%1440=468 -> 468/60=7, 468%60=48 -> 输出07:48,正确。 再测试一个边界:t_total=480,那么480-480=0,输出00:00,也就是0点出发,刚好8点到(因为0点出发,经过480分钟正好8点)。 再测试:t_total=481,那么480-481=-1,取模1440还是-1,然后调整:-1+1440=1439分钟,1439/60=23,1439%60=59,所以输出23:59(即前一天的23:59)。 所以代码正确。 注意:题目要求输出两位,所以用printf的%02d。 因此,我们使用修改后的版本。 §§相关问题§§: 1. 如果题目要求考虑秒,即速度是米每秒,而时间需要精确到秒,该如何修改? 2. 如果垃圾分类的时间不是整数,而是可以是小数(比如10.5分钟),代码如何调整? 3. 如果出发时间可以提前任意多天(比如提前一周),那么代码应如何修改以输出具体日期? 4. 在计算向上取整时,除了使用`(s+v-1)/v`,还有哪些方法?(比如使用浮点数函数ceil)</think>### 解决思路 题目要求计算在不迟到的前提下,最晚的出发时间。学校要求8:00到达,需要考虑以下时间: 1. 走路时间:距离(s) ÷ 速度(v),需要向上取整(因为不足一分钟也要算一分钟) 2. 垃圾分类时间:固定10分钟 核心步骤: 1. 计算总耗时 = 向上取整(s/v) + 10分钟 2. 从8:00(480分钟)向前倒推总耗时 3. 处理跨天情况(提前一天出发) 4. 格式化输出时间(HH:MM格式,不足两位补0) ### C++代码实现 ```cpp #include <iostream> #include <iomanip> using namespace std; int main() { int s, v; cin >> s >> v; // 计算走路时间(向上取整) int walk_time = (s + v - 1) / v; // 总耗时 = 走路时间 + 垃圾分类时间 int total_time = walk_time + 10; // 从8:00(480分钟)向前倒推 int departure_minutes = 480 - total_time; // 处理跨天情况(提前一天) if (departure_minutes < 0) { departure_minutes += 24 * 60; // 加上一天的分钟数 } // 转换为小时和分钟 int hour = departure_minutes / 60; int minute = departure_minutes % 60; // 格式化输出(两位数字,不足补0) cout << setfill(&#39;0&#39;) << setw(2) << hour << ":" << setfill(&#39;0&#39;) << setw(2) << minute << endl; return 0; } ``` ### 代码解释 1. **输入处理**:读取距离`s`(米)和速度`v`(米/分钟) 2. **向上取整计算**: - `(s + v - 1) / v` 实现向上取整的整数除法 - 如:s=100, v=99 → (100+99-1)/99 = 198/99 = 2 3. **总耗时计算**: - `walk_time` 是走路所需时间 - 加上固定的垃圾分类时间10分钟 4. **时间倒推**: - 8:00 相当于480分钟(8×60) - 向前倒推总耗时:480 - total_time 5. **跨天处理**: - 如果结果是负数,加上1440分钟(24小时) - 如:-20分钟 → -20+1440=1420分钟 → 23:40 6. **格式化输出**: - 使用`setfill(&#39;0&#39;)`和`setw(2)`确保小时和分钟都是两位数 - 如:7小时5分钟 → 07:05 ###验证 输入:`100 99` 1. 走路时间:ceil(100/99) = 2分钟 2. 总耗时:2 + 10 = 12分钟 3. 出发时间:480 - 12 = 468分钟 4. 转换:468÷60=7小时,468%60=48分钟 5. 输出:`07:48`(补0后为07:48)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值