PAT甲级真题 1072 Gas Station (30分) C++实现(Dijkstra算法,测试点4四舍五入的坑)

博客讲述了如何解决PAT甲级编程题1072 Gas Station,重点在于使用Dijkstra算法求解,并指出了在处理四舍五入时的坑点,导致测试点4出现问题。博主分享了解决这个问题的经验和最终正确输出的结果。
摘要由CSDN通过智能技术生成

题目

A gas station has to be built at such a location that the minimum distance between the station and any of the residential housing is as far away as possible. However it must guarantee that all the houses are in its service range.

Now given the map of the city and several candidate locations for the gas station, you are supposed to give the best recommendation. If there are more than one solution, output the one with the smallest average distance to all the houses. If such a solution is still not unique, output the one with the smallest index number.

Input Specification:
Each input file contains one test case. For each case, the first line contains 4 positive integers: N (≤1000), the total number of houses; M (≤10), the total number of the candidate locations for the gas stations; K (≤10000​​ ), the number of roads connecting the houses and the gas stations; and Ds​, the maximum service range of the gas station. It is hence assumed that all the houses are numbered from 1 to N, and all the candidate locations are numbered from G1 to GM.

Then K lines follow, each describes a road in the format

P1 P2 Dist

where P1 and P2 are the two ends of a road which can be either house numbers or gas station numbers, and Dist is the integer length of the road.

Output Specification:
For each test case, print in the first line the index number of the best location. In the next line, print the minimum and the average distances between the solution and all the houses. The numbers in a line must be separated by a space and be accurate up to 1 decimal place. If the solution does not exist, simply output No Solution.

Sample Input 1:
4 3 11 5
1 2 2
1 4 2
1 G1 4
1 G2 3
2 3 2
2 G2 1
3 4 2
3 G3 2
4 G1 3
G2 G1 1
G3 G2 2

Sample Output 1:
G1
2.0 3.3

Sample Input 2:
2 1 2 10
1 G1 9
2 G1 20

Sample Output 2:
No Solution

思路

首先处理输入中加油站的编号“G1~G10”,将其统一编号到房子之后,比如G1视为n+1。

一开始用Floyd算法求多源最短路径,果断超时了。

改用Dijkstra算法,以每个加油站为源点求单源最短路径,由于m最大值为10,最多只需求10次,解决了超时问题。

对于dist[Gi],检查其与所有房子之间最小距离dist[Gi][i],若其中有超过Ds的,则放弃该选择;若所有距离均在Ds内,则记录其中的最小值minGi 和平均距离 aveGi。

从所有minGi中找最大的;若有并列,再顺序找出其中aveGi最小的第一个即为所求。

坑点

  1. 一开始测试点4出现运行时错误,原因是将节点编号当做了最多2位,其实它们最大能取到1000 G10 这样的,需要将除了’G’以外的所有字符串转换为数字。

  2. 测试点4一直答案错误。一开始输出最后结果时为了四舍五入,将平均值加上了0.05后再用"%.1f"打印;看了网上许多代码发现并没有采用+0.05的方式,而是只有“%.1f”。查了资料发现%.1f会自动执行四舍五入的操作,但经过测试,值时3.25时打印出的是3.2,3.26时打印出3.3,值为3.251时也打印出3.3。当结果正好是X.X5时,%.1f的四舍五入结果是不对的。

去掉+0.05后,输入测试用例1,结果如下(调试环境:Mac XCode):
XCode输出结果
而题目中给的却是:
G1
2.0 3.3

然而这时却能AC了,测试点4不再报错……

有点神奇。如有知道问题原因的请不吝赐教。

代码

#include <iostream>
#include <vector>
#include <climits>
using namespace std;

struct Solution{
     //可行解
    int index;
    float minDist;
    float average;
};
int main(){
   
    int n, m, k, ds;
    scanf("%d %d %d %d", &n, 
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值