鱼C论坛

 找回密码
 立即注册
查看: 5627|回复: 9

这一点点差错是怎么回事?求大虾指教!

[复制链接]
发表于 2013-9-11 20:59:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
题目:
一个球从100m的高度自由落下,每次落地后反跳回原高度的一半,再落下,再反弹。求它在第十次落地时,共经过多少米,第十次反弹多高。

#include<stdio.h>
int main()
{
  double n=100.0,s,sum=0;   
  int  i;
  for(i=1;i<=10;i++)
  {
   s=n/2.0;
   sum=sum+s*2;
   n=n/2.0;   
  }
  printf("第十次弹跳高度为%f米\n",s);
  printf("十次共经过%f米\n",sum+100);
  return 0;
}


这是我写出来的程序。但是答案却值正确了一个。第十次弹跳高度是对的,但总米数不对,
这是第一次运行结果
123123123132.jpg


然后由于和书上答案不符合,我捉摸是不是i的初始值附错了,便把i=1改为i=2; 结果又变成了十次总米数正确,而第十次弹跳高度不对,我发现我要吐血了
第二次运行结果如下:
456456456456.jpg

我各种郁闷了,下面是书上的标准答案
#include<stdio.h>
int main()
{
  double sn=100,hn=sn/2;
  int n;
  for(n=2;n<=10;n++)
  {
   sn=sn+2*hn;
   hn=hn/2;
  }
  printf("第十次落地时共经过%f米\n",sn);
  printf("第十次反弹%f米\n",hn);
  return 0;
}


标准程序运行结果为:
8525822.jpg
求高手指教下我的错在哪里了呢?为什么呢?各种求帮助!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-9-11 21:58:01 | 显示全部楼层
因为除了第一次,之后的每次弹起来和再次掉下去都是一样的值会重复一次,所以需要2*hn,循环从2开始。
hn = hn / 2  每次弹起来高度会减半
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-9-12 02:22:17 | 显示全部楼层
感觉用面向对象解决比较容易,C++实现:
class Ball
{
    double TotalRoad;    //经过的总距离
    double OneTimeJump;  //当前一次跳的高度
    double OneTimeRoad;  //当前一次经过距离
    double height;       //当前所处高度
    int time;            //当前跳的第几次
public:
    Ball()
    {
        TotalRoad = 0.0;
        OneTimeJump = 0.0;
        OneTimeRoad = 0.0;
        height = 100.0;
        time = 0;
    }
    void JumpOneTime();
    double GetTotalRoad() { return TotalRoad; }
    double GetOneTimeJump() { return OneTimeJump; }
    int Gettime() { return time;}
   
};

void Ball::JumpOneTime()  //跳一次
{
    OneTimeRoad = height + height/2;
    OneTimeJump = height/2;
    height /= 2;
    TotalRoad += OneTimeRoad;
    ++time;
}


#include <iostream>

int main()
{
    Ball XiaoJiayu;   //创建小甲鱼球
   
    for (int i=0; i < 10; i++)   //小甲鱼跳十次
    {
        XiaoJiayu.JumpOneTime();
        std::cout << "The #" << XiaoJiayu.Gettime() << " time: \n";
        std::cout << "已经经过 " << XiaoJiayu.GetTotalRoad() << " 米";
        std::cout << "弹起高度为: " << XiaoJiayu.GetOneTimeJump() << "米\n";
    }
   
   
    return 0;
}
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-9-12 08:37:18 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-9-12 08:43:19 | 显示全部楼层
福禄娃娃 发表于 2013-9-11 21:58
因为除了第一次,之后的每次弹起来和再次掉下去都是一样的值会重复一次,所以需要2*hn,循环从2开始。
hn  ...

我能看懂标准答案的程序,但不知道我的程序哪里出错了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-9-12 09:19:19 | 显示全部楼层
With_You 发表于 2013-9-12 08:43
我能看懂标准答案的程序,但不知道我的程序哪里出错了

你的程序这么修改就对了
  1. # include <stdio.h>

  2. int main(void)
  3. {
  4.         double n = 100.0, s = 0.0, sum = 0.0;   
  5.         int  i;

  6.         for(i = 1; i <= 10; i++)
  7.         {
  8.                 s = n + n/2;
  9.                 sum = sum + s;
  10.                 n = n/2;

  11.                   
  12.         }
  13.         printf("十次共经过%f米\n", sum-n);
  14.         printf("第十次弹跳高度为%f米\n", n);
  15.        

  16.         return 0;
  17. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-9-12 09:54:45 | 显示全部楼层
首先你的程序for循环,循环10次没有错,因为你循环的初始值s为100,标准程序循环的初始值为50,所以他是9次。

循环10次,为嘛你的结果不对,你打印下每次的结果,你就知道了,

2次 经过200.000000
3次 经过250.000000
4次 经过275.000000
5次 经过287.500000
6次 经过293.750000
7次 经过296.875000
8次 经过298.437500
9次 经过299.218750
10次 经过299.609375
第十次落地时共经过299.609375米
第十次反弹0.097656米
1次 经过200.000000
2次 经过250.000000
3次 经过275.000000
4次 经过287.500000
5次 经过293.750000
6次 经过296.875000
7次 经过298.437500
8次 经过299.218750
9次 经过299.609375
10次 经过299.804688
第十次弹跳高度为0.097656米
十次共经过299.804688米

小球第一次落地经过了100次,而你自己的呢,多算了一次。程序你自己改吧,问题原因帮你找到了!,这样的逻辑问题,是跟编程的语法没关的,自己多想吧!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-9-12 10:02:12 | 显示全部楼层
本帖最后由 苹果沃珂 于 2013-9-12 10:09 编辑

你的错误主要是编程的逻辑错误:
1, 在for()循环中,你不清楚 i=1,i=2,i=3分别代表的意义;
2, 你不知道 i=1,i=2,i=3之间的有没有不一样的。

  根据你的程序代码,一次操作是从“球弹起”到“球落地”作为一个周期的,所以一次操作的路程为 s*2,累计路程为sum=sum+s*2;
你的错误如下:
   i=1,代表了第一次落地,这个第一次是直接从高度n=100下落的,这个没有从地上“弹起”的前半过程。
所以一次操作的路程为 s*1;
   i=2,代表了第二次,这次落地前,有从地上弹起的前半过程也有落地的后半过程,所以一次操作的路程为 s*2。
    i=3,4,……同i=2一样,含有完整的过程,所以一次操作的路程为 s*2。
  1. #include<stdio.h>
  2. int main()
  3. {
  4.         double n=100.0,s,sum=0;   
  5.         int  i;
  6.         for(i=1;i<=10;i++)
  7.         {
  8.                 /* s=n/2.0;
  9.                 sum=sum+s*2;
  10.                 n=n/2.0; */  
  11.                 if (i==1)
  12.                 {
  13.                         s = 0; // 第一次落地前没有弹起
  14.                         sum = sum + n + s;
  15.                         s = n / 2;// 第一次落地后弹起的高度==第二次落地前弹起的高度
  16.                 }
  17.                 else
  18.                 {
  19.                         n = s; // 第i次落地前弹起的高度==第i-1次落地后弹起的高度
  20.                         sum = sum + s * 2;
  21.                         s = n / 2;// 第i次落地后弹起的高度==第i+1次落地前弹起的高度
  22.                 }
  23.         }
  24.         printf("第十次弹跳高度为%f米\n",s);
  25.         printf("十次共经过%f米\n",sum); // sum+100代表是的补充第一次的操作,现在已经在循环里面做了
  26.         return 0;
  27. }
  28. #include<stdio.h>
  29. int main()
  30. {
  31.         double n=100.0,s,sum=0;   
  32.         int  i;
  33.         for(i=1;i<=10;i++)
  34.         {
  35.                 /* s=n/2.0;
  36.                 sum=sum+s*2;
  37.                 n=n/2.0; */  
  38.                 if (i==1)
  39.                 {
  40.                         s = 0; // 第一次落地前没有弹起
  41.                         sum = sum + n + s;
  42.                 }
  43.                 else
  44.                 {
  45.                         s = n / 2;// 第i次落地前弹起的高度==第i-1次落地后弹起的高度==第i次落地高度的一半
  46.                         sum = sum + s * 2;
  47.                         n = s; // 第i次落地后高度
  48.                 }
  49.         }
  50.         printf("第十次弹跳高度为%f米\n",s/2);//因为第10次弹跳高度==第11次落地高度==第10次落地高度的一半
  51.         printf("十次共经过%f米\n",sum); // sum+100代表是的补充第一次的操作,现在已经在循环里面做了
  52.         return 0;
  53. }
复制代码


小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-9-12 10:38:26 | 显示全部楼层
1落0弹……10落9弹,10弹路程不计入10落总路程,sum+100-2*s
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-9-12 10:50:38 | 显示全部楼层
建议lz不清楚的时候,先用debug模式,然后在考量自己的逻辑是否有问题。。
一般情况下,编译没问题,那么语法的问题就不大可能。。
所以要明确逻辑。。

ps:逻辑ok了,问题就差不多了。。然后把逻辑的思路调理化,再开始写代码,这个问题想出问题都难
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-11-6 07:36

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表