这是一题求多点路线问题,每两个点之间都可能存在关系,可以用dfs,不过如果有环的话就会爆栈,也可以有floy直接暴搜。关键在于浮点型计算的时候回丢精度,可以每次都不做浮点型的乘除法,最后在运算。不过这题在取整的时候为啥要减一个精度,还是不太明白。
double类型的精度只能达到小数点后16位,大于16位就不能比较大小了。所以浮点型还是慎用。
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <set>
#define INF 1000000005
#define ep 1e-8
using namespace std;
map<string,int> q;
string q2[33];
double d[33][33];
void floy(int n)
{
for(int k=0;k<n;k++)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(d[i][k]!=INF&&d[k][j]!=INF&&i!=j&&k!=i&&k!=j)
{
d[i][j]=d[i][k]*d[k][j];
}
}
}
}
}
void init()
{
for(int i=0;i<33;i++)
{
d[i][i]=1;
for(int j=0;j<33;j++)
{
if(i!=j)
d[i][j]=INF;
}
}
q.clear();
}
int main()
{
int n,tt=1;
while(scanf("%d",&n)==1)
{
if(!n) break;
init();
int p=0;
for(int i=0;i<n;i++)
{
int a,b;
string sa,sb;
int ia,ib;
char sc[10];
scanf("%d",&a);cin>>sa;
if(q.count(sa)==0)
{
q[sa]=p++;
}
ia=q[sa];
q2[ia]=sa;
scanf("%s",sc);
scanf("%d",&b); cin>>sb;
if(q.count(sb)==0)
{
q[sb]=p++;
}
ib=q[sb];
q2[ib]=sb;
d[ia][ib]=(double)b/(double)a;
d[ib][ia]=(double)a/(double)b;
}
double num;
string s;
scanf("%lf",&num); cin>>s;
int id=q[s];
floy(p);
double eps=INF;
int ansnum;
string ansname;
for(int i=0;i<p;i++)
{
if(d[id][i]!=INF&&id!=i)
{
int tmpnum=(int)ceil(num*d[id][i]-ep);//这里要保留精度取整
if(tmpnum>100000) continue;//这里没看到
double tmpeps=(double)tmpnum*d[i][id];
if(tmpeps<eps)
{
eps=tmpeps;
ansnum=tmpnum;
ansname=q2[i];
}
}
}
printf("Case %d: %d ",tt++,ansnum);
cout<<ansname<<endl;
}
return 0;
}