#12446: C++牛頓法


jykuo1020 (ΔEΔt>=ћ/2)

學校 : 國立臺灣師範大學附屬高級中學
編號 : 60232
來源 : [124.219.6.236]
最後登入時間 :
2019-12-27 15:25:06
d854. NOIP2001 1.一元三次方程求解 -- NOIP2001提高组第一题 | From: [103.246.208.218] | 發表日期 : 2017-07-26 23:06

#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

inline long double x0(long double a,long double b,long double c,long double d){
	return (a+b+c+d)/4;}
inline long double f(long double x,long double a,long double b,long double c,long double d){
	return ((a*pow(x,3))+(b*pow(x,2))+(c*x)+d);}
inline long double fp(long double x,long double a,long double b,long double c){
	return ((3*a*pow(x,2))+(2*b*x)+c);}
long double dp(long double x0,long double a,long double b,long double c,long double d){
	int w=1000;double ans=x0-(f(x0,a,b,c,d)/fp(x0,a,b,c));
	while(w--){
		ans=ans-(f(ans,a,b,c,d)/fp(ans,a,b,c));}
	return ans;}
int main(int argc, char** argv) {
	long double a,b,c,d;
	while(cin>>a>>b>>c>>d){
		long double x1=dp(x0(a,b,c,d),a,b,c,d);
		long double A=(-b/a)-x1;
		long double C=(-d)/(a*x1);
		long double x2=(A+sqrt(A*A-(4*C)))/2;
		long double x3=(A-sqrt(A*A-(4*C)))/2;
		long double k[3]={x1,x2,x3};
		sort(k,k+3);
		printf("%.2Lf %.2Lf %.2Lf\n",k[0],k[1],k[2]);
	}
	
	return 0;
}
 
#12451: Re:C++牛頓法


who_am_I (kruztw)

學校 : 國立臺灣師範大學
編號 : 54056
來源 : [36.224.144.147]
最後登入時間 :
2023-04-22 22:46:31
d854. NOIP2001 1.一元三次方程求解 -- NOIP2001提高组第一题 | From: [140.122.136.39] | 發表日期 : 2017-07-27 11:09

#include 
#include 
#include 
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

inline long double x0(long double a,long double b,long double c,long double d){
	return (a+b+c+d)/4;}
inline long double f(long double x,long double a,long double b,long double c,long double d){
	return ((a*pow(x,3))+(b*pow(x,2))+(c*x)+d);}
inline long double fp(long double x,long double a,long double b,long double c){
	return ((3*a*pow(x,2))+(2*b*x)+c);}
long double dp(long double x0,long double a,long double b,long double c,long double d){
	int w=1000;double ans=x0-(f(x0,a,b,c,d)/fp(x0,a,b,c));
	while(w--){
		ans=ans-(f(ans,a,b,c,d)/fp(ans,a,b,c));}
	return ans;}
int main(int argc, char** argv) {
	long double a,b,c,d;
	while(cin>>a>>b>>c>>d){
		long double x1=dp(x0(a,b,c,d),a,b,c,d);
		long double A=(-b/a)-x1;
		long double C=(-d)/(a*x1);
		long double x2=(A+sqrt(A*A-(4*C)))/2;
		long double x3=(A-sqrt(A*A-(4*C)))/2;
		long double k[3]={x1,x2,x3};
		sort(k,k+3);
		printf("%.2Lf %.2Lf %.2Lf\n",k[0],k[1],k[2]);
	}
	
	return 0;
}

簡單說明:

這位大大使用的方法為牛頓近似法,而不是牛頓因式檢驗法

函數 x0  用來設定起點

函數 f    將x0代入方程式

函數 fp   將方程式做微分並把值代入

函數dp  是用來做垂切,也就是找尋近似值的步驟,此處執行1001次以求近似

 

函數 main 裡面

第一步是先找出一個近似根

接著利用根與係數

求出兩根和、兩根積

再利用平方公式解出兩根

最後小到大排序並輸出

 
ZeroJudge Forum