10年第六届湖南省acm程序设计大赛 第五题 E 内部收益率
題目E
內部收益率
?
在金融中,我們有時會用內部收益率IRR來評價項目的投資財務效益,它等于使得投資凈現值NPV等于0的貼現率。換句話說,給定項目的期數T、初始現金流CF0和項目各期的現金流CF1, CF2, ...,CFT,IRR是下面方程的解:
?
?
為了簡單起見,本題假定:除了項目啟動時有一筆投入(即初始現金流CF0 < 0)之外,其余各期均能賺錢(即對于所有i=1,2,...,T,CFi > 0)。根據定義,IRR可以是負數,但不能大于-1。
?
?
輸入
輸入文件最多包含25組測試數據,每個數據占兩行,第一行包含一個正整數T(1<=T<=10),表示項目的期數。第二行包含T+1個整數:CF0, CF1, CF2, ..., CFT,其中CF0 < 0, 0 < CFi < 10000 (i=1,2,...,T)。T=0表示輸入結束,你的程序不應當處理這一行。
輸出
對于每組數據,輸出僅一行,即項目的IRR,四舍五入保留小數點后兩位。如果IRR不存在,輸出"No",如果有多個不同IRR滿足條件,輸出"Too many"(均不含引號)
?
| 樣例輸入 | 樣例輸出 |
| 1 -1 2 2 -8 6 9 0 | 1.00 0.50 |
?
如果想直接解出這個方程 基本上是不可能的
那么我們換種思維? 我們使用窮舉法來做 但是一個一個值窮舉又太不現實了
介于方程特殊性 我們使用二分查找法能大大縮短窮舉量
#include<stdio.h>
int cf[11];
int T;
double f(double IRR)//求方程式左邊的值函數,sum相當于NPV
{
?double a=1,sum=0;
?for(int i=0;i<=T;i++)
?{
??sum+=cf[i]/a;
??a*=IRR;
?}
?return sum;
}
void main()
{
?int i,k=0;
?double m=1e6,n=0,IRR;//m上界 n下界 IRR實際上等于題目中的IRR+1;
?while(scanf("%d",&T)&&T&&k<=100)//如果不設置一個k值無解情況下很可能程序會陷入死循環
?{k++;
??for(i=0;i<=T;i++)
???? scanf("%d",&cf[i]);
???? IRR=m/2;
???? while(f(IRR)!=0)
??{
???if(f(m)*f(IRR)<=0)n=IRR;//如果區間存在解 必定一個值大于零一個值小于零
???if(f(n)*f(IRR)<=0)m=IRR;
???IRR=(m+n)/2;
??}
??? printf("%.2f/n",IRR-1);
?}
}
?
原方法:
#include<stdio.h>
int main() {
? int n;
? int cf[20];
? while(scanf("%d", &n) == 1) {
??? if(!n) break;
??? for(int i = 0; i <= n; i++) scanf("%d", &cf[i]);
??? double l = -1.0, r = 1e6, m;
??? for(int i = 0; i < 100; i++) {
????? m = l + (r-l)/2;
????? double f = 1.0, s = 0;
????? for(int j = 1; j <= n; j++) {
??????? f /= (1+m);
??????? s += cf[j]*f;
????? }
????? if(s < -cf[0]) r = m; else l = m;
??? }
??? printf("%.2lf/n", m);
? }
? return 0;
}
總結
以上是生活随笔為你收集整理的10年第六届湖南省acm程序设计大赛 第五题 E 内部收益率的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 绘画EQ训练减压一体机--减压训练、绘画
- 下一篇: php获取时间不正确,php date(