银行贷款
源程序名    LOAN.??? (PAS,C,CPP)
可执行文件名   LOAN.EXE
输入文件名   LOAN.IN 
输出文件名     LOAN.OUT当一个人从银行贷款后,在一段时间内他(她)将不得不每月偿还固定的分期付款。这个问题要求计算出贷款者向银行支付的利率。假设利率按月累计。输入:
输入文件仅一行包含三个用空格隔开的正整数。
第一个整数表示贷款的原值,第二个整数表示每月支付的分期付款金额,第三个整数表示分期付款还清贷款所需的总月数。输出:
输出文件应该是一个实数,表示该贷款的月利率(用百分数表示),四舍五入精确到0.1%。样例
LOAN.IN
1000 100 12LOAN.OUT
2.9//////////////////////////////////////////////////////////////////////////
下面是程序
/////////////////////////////////////////////////////////////////////////
var total,pay,year,i:longint;
    rate,l,r,now:real;
begin
     assign(input,'loan.in');
     reset(input);
     readln(total,pay,year);
     r:=1;
     l:=0;
     while r-l > 1e-5 do
     begin
          rate := (l + r) /2 ;
          now := total;
          for i:=1 to year do now := now*(rate+1) - pay;
          if now < 0 then l := rate
          else r := rate;
     end;
     writeln(rate*100:0:2);
end.
但是不明白是什么意思,大家解释一下好吗?

解决方案 »

  1.   

    procedure TForm1.Button1Click(Sender: TObject);
    var total,pay,year,i:longint;
        rate,l,r,now:real;
    begin
    //二分法,逐步毕竟,让左右两点误差小于某数字就是最后结果,比如10^-5也就是1e-5
         assign(input,'loan.in');     //读取文件
         reset(input);
         readln(total,pay,year);      //数据
         r:=1;                        //右(可能最大)
         l:=0;                        //左(可能最小)
         while r-l > 1e-5 do          //大于误差则不断计算
         begin
              rate := (l + r) /2 ;    //利率取两点平均 第一次0.5
              now := total;           //
              for i:=1 to year do now := now*(rate+1) - pay; //计算每月利率+本金-还款
              if now < 0 then l := rate     //利率设的低了..增加最小(左)
              else r := rate;               //利率设的高了..减小最大(右)
         end;
         writeln(rate*100:0:2);
    end.
      

  2.   

    就像微分一样,不能求出确切值,只能求出一个误差足够小的范围.
    第一次范围就是0-1,利率0.5  显然结果是 跳转到 now>0也就是else的那句r:=0.5
    第二次范围就是0-0.5 ,利率0.25        同上
    第三次范围就是0-0.25 利率0.125       同上...
    依次类推
      

  3.   

    和它等价的算法procedure TForm1.Button2Click(Sender: TObject);
    var total,pay,year:longint;
      function Loan(r,l:real):real;
      var now:real;
        i:integer;
      begin
        result:=(l+r)/2;
        if r-l>1e-5 then
        begin
          now:=total;
          for i:=1 to year do now := now*(result+1) - pay;
          if now<0 then
            result:=Loan(r,result)
          else
            result:=Loan(result,l);
        end
      end;
    begin
        total:=1000;
        pay:=100;
        year:=12;
        showmessage(floattostr(loan(1,0)));
    end;