龟兔赛跑模拟
问题描述:兔子虽然跑比乌龟快,但它们有众所周知的毛病——骄傲且懒惰,于是在与乌龟的比赛中,一旦任一秒结束后兔子发现自己领先t米或以上,它们就会停下来休息s秒。对于不同的兔子,t,s的数值是不同的,但是所有的乌龟却是一致——它们不到终点决不停止。只要在每场比赛开始后记录下兔子和乌龟的数据——兔子的速度v1(表示每秒兔子能跑v1米),乌龟的速度v2,以及兔子对应的t,s值,以及赛道的长度l——就能预测出比赛的结果。写一个程序,对于输入的一场比赛的数据v1,v2,t,s,l,预测该场比赛的结果。输入格式:输入只有一行,包含用空格隔开的五个正整数v1,v2,t,s,l,其中(v1,v2<=100;t<=300;s<=10;l<=10000且为v1,v2的公倍数)
输出格式:输出包含两行,第一行输出比赛结果——一个大写字母“T”或“R”或“D”,分别表示乌龟获胜,兔子获胜,或者两者同时到达终点。第二行输出一个正整数,表示获胜者(或者双方同时)到达终点所耗费的时间(秒数)。
样例输入10 5 5 2 20
样例输出D \n(换行) 4
解题过程很是曲折。我刚开始的思路是:利用时间的关系进行判断。先求出兔子、乌龟各自跑完全程的时间h1\h2,在对他们之后每一个阶段所需要的时间进行判断,求出谁最先跑完全程,并且记录时间。最初是把第一个一起跑的阶段分开写了,后来发现可以合并,那怎么能多敲呢,所以,我就省略合并了。我把示例给的值带进去,全部通过。但是当我递交系统测评的时候,竟然报的“未全部正确,只有60分”!???这种怎么回事?当我把系统测试的错误数据下载下来后,我惊讶了。怎么还有这杨样的操作!!共同跑时,从开始到相差t距离的时间,竟然是分数!!计算机可是不玩分数的啊!!下面先放我的错误代码,给大家提醒一下。
#include<stdio.h>
int main()
{
double temp;//辅助记录函数,用于暂存第i次兔子超过乌龟t米所需时间
int h1,h2;//用于记录兔子、乌龟跑完全程所需的总时间
double p1=0,p2=0;//用于记录兔子、乌龟已经跑过的时间
int v1,v2,t,s,l;
double r1,r2;//用于记录兔子、乌龟跑过剩下路程所需的时间
scanf("%d %d %d %d %d",&v1,&v2,&t,&s,&l);
//进行龟兔追赶的模拟
h1=l/v1;
h2=l/v2;
while(p1<h1&&p2<h2)//兔子和乌龟都没有跑完
{
temp=(p2*v2+t-p1*v1)/(v1-v2);
if(p1+temp>=h1&&p2+temp<h2)//只有兔子跑完r1<r2
{
printf("R\n");
printf("%d",h1+s);//时间是兔子跑的时间+休息的时间
return 0;
}
else
{
if(p1+temp>=h1&&p2+temp>=h2)//乌龟先到,或者双方同时到达
{
r1=h1-p1;//兔子剩下需要跑的时间
r2=h2-p2;//乌龟剩下需要跑的时间,前面的那个休息确定可以执行完整之后,p2已经更新
if(r1==r2)//一起跑完
{
printf("D\n");
printf("%d",h2);//时间是兔子跑的时间+休息的时间
return 0;
}
else//r1>r2或者r1<r2
{
if(r1>r2)
{
printf("T\n");
printf("%d",h2);//时间是兔子跑的时间+休息的时间
return 0;
}
else//r1<r2
{
printf("R\n");
printf("%d",h1+s);//时间是兔子跑的时间+休息的时间
return 0;
}
}
}
}
//有休息的时刻,如果在此过程中完成,只可能是乌龟完成,因为兔子在休息
p1+=temp;
p2+=temp;
if(p2+s>=h2)//乌龟完成
{
printf("T\n");
printf("%d",h2);
return 0;
}
p2+=s;
}
return 0;
}
不通过后,我试图去解决分数的问题,看看可不可以让分数换成多为小数存储。然而,系统无情的告诉我:不可以!于是,我就老老实实在网上寻求大佬的帮助。然后,就找到了大佬的在我看来,思维极为巧妙的代码,虽然是Java语言写的,但是整体的思路,作为一个Java方面憨憨的我还是可以看的差不多的。先放上大佬的博文链接:
大佬的原博文,点此处
后来,仔细阅读题目,明确说明了“v1,v2<=100;t<=300;s<=10;l<=10000且为v1,v2的公倍数”,原来,是在暗示我用距离来算啊。都怪我太年轻!
下面放上以大佬的思路为基础的C语言代码:
#include<stdio.h>
int main()
{
int v1,v2,t,s,l;//输入的变量
int time=0;//记录时间的变量
int l1=0,l2=0;//记录l1、l2运动距离的变量
int flag=0;//标志位,用于辅助判断是否跑完
int i;//循环控制变量
scanf("%d %d %d %d %d",&v1,&v2,&t,&s,&l);
//利用单位时间的运动距离,来进行距离判断,比传统的数学计算(用一定的距离和时间要方便)
while(1)//循环的终止条件设立在循环内部判断
{
time++;//while循环每进行一次,代表着时间增加1秒
l1+=v1;
l2+=v2;
if(l1>=l||l2>=l)
break;//比赛结束,此种情况表示的是,兔子和乌龟都在跑步的时候,结束了比赛
if(l1-l2>=t)//这种情况是兔子在休息,乌龟在跑的时候结束了比赛
{
for(i=1;i<=s;i++)
{
time++;//时间也在流逝
l2+=v2;
if(l2>=l)
{
flag=1;//因为下边的break只能跳出for循环,不能跳出外层while循环
//设置flag标志符,是为了帮助跳出外层的while循环 (if不是循环,不用break)
break;//在兔子休息的过程中,乌龟完成了比赛
}
}
}
if(flag==1)
break;
}
//开始输出比赛结果,只用看 跑的距离,就可以判断出来是谁赢
if(l1>l2)
{
printf("R\n");
printf("%d",time);
return 0;
}
if(l1==l2)
{
printf("D\n");
printf("%d",time);
return 0;
}
if(l1<l2)
{
printf("T\n");
printf("%d",time);
return 0;
}
}