problem
Now,given the equation 8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 == Y,can you find its solution between 0 and 100;
Now please try your lucky.
Input
The first line of the input contains an integer T(1<=T<=100) which means the number of test cases. Then T lines follow, each line has a real number Y (fabs(Y) <= 1e10);
Output
For each test case, you should just output one real number(accurate up to 4 decimal places),which is the solution of the equation,or “No solution!”,if there is no solution for the equation between 0 and 100.
Sample Input
2
100
-4
Sample Output
1.6152
No solution!
思路
解一元高次方程,解给定了1~100这样一个区间,且保证了最多只有一个解
可以二分或者牛顿迭代法 先找到一个范围
二分法可能写搓了 还判了增减
还有一种更通用的方法,就是直接用递归解高次方程
具体见https://blog.youkuaiyun.com/feynman1999/article/details/80138789
代码见下文
牛顿迭代法
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int debug_num=0;
#define debug cout<<"debug "<<++debug_num<<" :"
double y;
double f(double x)
{
return (8*x*x*x*x+7*x*x*x+2*x*x+3*x+6-y);
}
double dao(double x)
{
return (32*x*x*x+21*x*x+4*x+3);
}
int main()
{
//freopen("in.txt","r",stdin);
//ios::sync_with_stdio(false);
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lf",&y);
//from 0 and 100 two close
//cout<<ans1<<' '<<ans2<<endl;
int flag=0;
for(double ans=0;ans<=100-0.5;ans=ans+0.5){
if(f(ans)*f(ans+0.5)>=0) continue;
double t=ans;
for(int i=0;i<20;++i){
t=t-f(t)/dao(t);
}
if(t>=0&&t<=100){
printf("%.4lf\n",t);
flag=1;
break;
}
}
if(!flag) printf("No solution!\n");
}
return 0;
}
二分法
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int debug_num=0;
#define debug cout<<"debug "<<++debug_num<<" :"
const double eps=1e-6;
double y;
double f(double x)
{
return (8*x*x*x*x+7*x*x*x+2*x*x+3*x+6-y);
}
int main()
{
//freopen("in.txt","r",stdin);
//ios::sync_with_stdio(false);
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lf",&y);
//from 0 and 100 two close
//cout<<ans1<<' '<<ans2<<endl;
int flag=0;
for(double ans=0;ans<=100-0.5;ans=ans+0.5){
if(f(ans)*f(ans+0.5)>0) continue;
//ÔÚans~ans+0.5Çø¼äÄÚ
double l=ans-0.5,r=ans+0.5;
if(r>l){//increse
while(r-l>eps)
{
double mid=(l+r)/2;
if(f(mid)>=0) r=mid;
else l=mid;
}
}
else{//decrese
while(l-r>eps)
{
double mid=(l+r)/2;
if(f(mid)<=0) r=mid;
else l=mid;
}
}
if(r>=0&&r<=100){
printf("%.4lf\n",r);
flag=1;
break;
}
}
if(!flag) printf("No solution!\n");
}
return 0;
}
通用方法(解高次方程)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int debug_num=0;
#define debug cout<<"debug "<<++debug_num<<" :"
const double eps=1e-12;
const double inf=1e12;
inline int sign(double x){
return x<-eps ? -1 : x>eps ;
}
//coef 系数 coef[i]=a[i]
inline double get(const vector<double> &coef,double x){//将x带入方程的值
double e=1,s=0;//e=x^i (i=0,1,2,...,n) coef.size():n+1
for(int i=0;i<coef.size();++i) s+=coef[i]*e,e*=x;
return s;
}
double Find(const vector <double> &coef,int n,double lo,double hi){
double sign_lo,sign_hi;
if((sign_lo=sign(get(coef,lo)))==0) return lo;//lo就是零点
if((sign_hi=sign(get(coef,hi)))==0) return hi;//hi就是零点
if(sign_hi*sign_lo>0) return inf;//当前区间没有零点
for(int step=0;step<100 && hi-lo>eps;++step){//标准二分
double m=(lo+hi)*.5;
int sign_mid=sign(get(coef,m));
if(sign_mid==0) return m;
if(sign_lo*sign_mid<0) hi=m;
else lo=m;
}
return (lo+hi)*.5;
}
vector<double> solve(vector<double> coef,int n){
vector<double> ret;
if(n==1){
if(sign(coef[1])) ret.push_back(-coef[0]/coef[1]);
return ret;//直接求解
}
vector<double> dcoef(n);//求导 大小只有n(原函数是n+1)
for(int i=0;i<n;++i) dcoef[i]=coef[i+1]*(i+1);
vector<double> droot=solve(dcoef,n-1);
droot.insert(droot.begin(),-inf);
droot.push_back(inf);//开头结尾插上-inf 和inf 方便二分 关键
for(int i=0;i+1<droot.size();++i){
double tmp=Find(coef,n,droot[i],droot[i+1]);
if(tmp<inf) ret.push_back(tmp);
}
return ret;
}
vector <double > ans;
vector <double > coef;
int main()
{
//freopen("in.txt","r",stdin);
//ios::sync_with_stdio(false);
int t;
int n;
//scanf("%d",&n);
n=4;
// for(int i=0;i<=n;++i){
// double tp;
// scanf("%lf",&tp);
// coef.push_back(tp);
// }
cin>>t;
while(t--){
ans.clear();
coef.clear();
coef.push_back(8);
coef.push_back(7);
coef.push_back(2);
coef.push_back(3);
double tp;
cin>>tp;
coef.push_back(6-tp);
reverse(coef.begin(),coef.end());//注意顺序看要不要逆序 coef[0]放的是x^0对应的系数
ans=solve(coef,n);
//sort(ans.begin(),ans.end());
int flag=0;
for(int i=0;i<ans.size();++i){
if(sign(ans[i])==1&&sign(ans[i]-100)==-1) printf("%.4f\n",ans[i]),flag=1;
}
if(flag==0) cout<<"No solution!"<<endl;
//coef.erase(coef.rbegin());
//coef.erase(coef.end()-1);
}
return 0;
}