pat1072 Gas Station
这道题是求M个候选点到N个house的最短路,从M个点中选符合条件的一个点。题目不难,由于没处理好几个细节,导致了很多bug。一开始wa以为是卡在int没有用longlong,但改完发现的其他bug后就A了,看来pat不会故意在数据大小上卡。
bug如下:
1、节点标号使用字符串读,转换为整数时只转换了一位,没有考虑到多位的情况。
2、求距离之和时sum的初始化放在了for循环的外面,应该放在for循环的第一句,否则只有第一个求的正确,后面的会累加。
3、求最小值该用>的地方写成<。
4、这个是最隐蔽的bug,题目说要保证候选点到house的距离in its service range,这里应该用<=,写成<,导致第一个case都没过。将题意转换成代码时没有转换正确。真是细节决定成败啊。
附代码:
1 //pat1072 Gas Station 2 #include<stdio.h> 3 #include <stdlib.h> 4 #include <string> 5 #include <iostream> 6 using namespace std; 7 //总节点数 8 #define MAXN 1100 9 #define inf 2000000000 10 struct Candidate 11 { 12 int min,max; 13 double average; 14 }candidate[15]; 15 int map[MAXN][MAXN],Min[MAXN]; 16 //所有节点数=N+M,包含候选点,0到M-1为候选点,M到n-1为house 17 int n; 18 19 void dijkstra(int s,int* min) 20 { 21 int v[MAXN],i,j,k; 22 for (i=0;i<n;i++) 23 {min[i]=inf,v[i]=0;} 24 for (min[s]=0,j=0;j<n;j++) 25 { 26 //找距离最小的点,最初为源点 27 for (k=-1,i=0;i<n;i++) 28 { 29 if (!v[i]&&(k==-1||min[i]<min[k])) 30 k=i; 31 } 32 //比较从经过该点到其他点的距离与当前最小距离,更新当前最小距离 33 for (v[k]=1,i=0;i<n;i++) 34 { 35 if (!v[i]&&min[k]+map[k][i]<min[i]) 36 min[i]=min[k]+map[k][i]; 37 } 38 } 39 } 40 int char2int(char* p,int M) 41 { 42 int ans=0,j; 43 if(p[0]=='G') 44 { 45 j=1; 46 while(p[j]!='\0') 47 { 48 ans=ans*10+p[j]-'0'; 49 j++; 50 } 51 ans--; 52 } 53 else 54 { 55 j=0; 56 while(p[j]!='\0') 57 { 58 ans=ans*10+p[j]-'0'; 59 j++; 60 } 61 ans=ans+M-1; 62 } 63 return ans; 64 } 65 int main() 66 { 67 int i,j,N,M,K,Ds; 68 char p1[10],p2[10]; 69 while(scanf("%d%d%d%d",&N,&M,&K,&Ds)!=EOF) 70 { 71 n=N+M; 72 int dist,left,right; 73 for(i=0;i<n;i++) 74 { 75 for(j=i+1;j<n;j++) 76 map[i][j]=map[j][i]=inf; 77 } 78 for(i=0;i<K;i++) 79 { 80 scanf("%s%s%d",p1,p2,&dist); 81 left=right=0; 82 left=char2int(p1,M); 83 right=char2int(p2,M); 84 map[left][right]=map[right][left]=dist; 85 } 86 //求各个候选点到所有house的距离,记录最大值和最小值 87 int sum=0; 88 for(i=0;i<M;i++) 89 { 90 candidate[i].min=inf; 91 candidate[i].max=0; 92 } 93 for(i=0;i<M;i++) 94 { 95 dijkstra(i,Min); 96 sum=0; 97 for(j=M;j<n;j++) 98 { 99 if(j==M||Min[j]<candidate[i].min) 100 candidate[i].min=Min[j]; 101 if(j==M||Min[j]>candidate[i].max) 102 candidate[i].max=Min[j]; 103 sum+=Min[j]; 104 } 105 candidate[i].average=(sum+0.0)/N; 106 } 107 //在最大值小于等于Ds的情况下找最小值最大的 108 int ans=-1; 109 for(i=0;i<M;i++) 110 { 111 if(candidate[i].max<=Ds) 112 { 113 if(ans==-1||candidate[i].min>candidate[ans].min) 114 { 115 ans=i; 116 } 117 else if(candidate[i].min==candidate[ans].min&&candidate[i].average<candidate[ans].average) 118 { 119 ans=i; 120 } 121 } 122 } 123 if(ans==-1) 124 printf("No Solution\n"); 125 else 126 printf("G%d\n%.1f %.1f\n",ans+1,candidate[ans].min+0.0,candidate[ans].average); 127 } 128 129 return 0; 130 }