额、、、、第一次解高次方程,吓着自己了。看了很多资料(跑偏了,找各种数学公式去了、、、、正在筹备总结学过的各种数论知识点)。加油!!!吖飒~~~~
hdu2199
题意:
求解8x^4+7x^3+2x^2+3x+6-m=0;这个方程式。
分析:
二分法比较容易。代码比较好写。开始一直觉得二分肯定超时,没敢写代码。后来,写了写才知道直接AC。时间分析,x属于【0-100】,即使是浮点数,也不过多循环几次。二分耗时:log2n,是很小的数。
(警示,一定要论证后,再确定是不是超时。确定思路不会超内存,超时后再去写代码,省去无谓的时间)
代码:
#include <iostream> #include<stdio.h> using namespace std; #define INF 0.000001 #define MIN 0.0000001 double m; double fun(double x) { return 8*x*x*x*x+7*x*x*x+2*x*x+3*x+6; } int main() { int n; cin>>n; while(n--) { cin>>m; double first=0;double end=100; double mid; if(fun(0)>m||fun(100)<m) cout<<"No solution!"<<endl; else { while(end-first>INF) { mid=(first+end)/2.0; if(fun(mid)>m) {end=mid+MIN;} else if(fun(mid)<m) {first=mid-MIN;} } printf("%.4lf\n",(first+mid)/2.0); } } return 0; }
感冒相当严重呀、、、回去睡觉
嘿嘿。。。还是写了写 牛顿迭代,不过可能是精度的问题,数值有点偏大;思想是对的
代码附上:
#include<iostream> #include<cmath> #include<stdio.h> using namespace std; #define INF 0.000001 #define MIN 0.0000001 double x; double iteration(double m) { while(abs(8*x*x*x*x+7*x*x*x+2*x*x+6-m)>INF)//迭代过程控制 { x-=(8*x*x*x*x+7*x*x*x+2*x*x+6-m)/(32*x*x*x+21*x*x+4*x+3);//迭代关系式 } return x;//迭代变量 } int main() { int n; cin>>n; while(n--) { double m; cin>>m; x=100.0; if(8*x*x*x*x+7*x*x*x+2*x*x+6<m){cout<<"No solution!"<<endl;continue;} else if(6.0>m){cout<<"No solution!"<<endl;continue;} iteration(m); if(x-0<MIN) cout<<"No solution!"<<endl; else printf("%.4lf\n",x); } }
hdu 2899
二分解法的一个变形,由于函数F[x]=6 * x^7+8*x^6+7*x^3+5*x^2-y*x是凸函数
F'(x)=0时,函数有最小值。所以只需要 求解F‘(x)=0,把x带入即可。
代码:
//6 * x^7+8*x^6+7*x^3+5*x^2-y*x #include <iostream> #include<stdio.h> using namespace std; #define INF 0.0000001 #define MIN 0.00000001 double m; double res(double x) { return 6*x*x*x*x*x*x*x+8*x*x*x*x*x*x+7*x*x*x+5*x*x-x*m; } double fun(double x) { return 42*x*x*x*x*x*x+48*x*x*x*x*x+21*x*x+10*x; } int main() { int n; cin>>n; while(n--) { cin>>m; double first=0;double end=100; double mid; while(end-first>INF) { mid=(first+end)/2.0; if(fun(mid)>m) {end=mid+MIN;} else if(fun(mid)<m) {first=mid-MIN;} } printf("%.4lf\n",res((first+mid)/2.0)); } return 0; }
hdu2141 Can you find it?
还是一个二分。稍微有些变形。
先计算好A+B,然后二分查找m-c。
其中 search函数可以写成二分查找的系统函数-binary_search(sum,sum+l*n,x-C[j]);//数组名,数组长度,要查找的数
代码:
#include<iostream> #include <algorithm> using namespace std; int A[505]; int B[505]; int C[505]; int sum[250005]; int l,m,n; bool search(int x) { int first=0;int end=l*n; int mid; while(first<=end) { mid=(first+end)/2; if(x<sum[mid]) end=mid-1; else if(x==sum[mid]) return true; else first=mid+1; } return false; } int main() { int i,j,s;int X; int cnt=1; while(~scanf("%d%d%d",&l,&n,&m)) { printf("Case %d:\n",cnt++); for(i=0;i<l;i++) scanf("%d",&A[i]); int k=0; for(i=0;i<n;i++) { scanf("%d",&B[i]); for(j=0;j<l;j++) sum[k++]=A[j]+B[i]; } sort(sum,sum+l*n); for(i=0;i<m;i++) scanf("%d",&C[i]); cin>>s; for(i=0;i<s;i++) { int flag=0; scanf("%d",&X); for(j=0;j<m;j++) { flag = search( X - C[j]); if(flag) break; } if(flag) printf("YES\n"); else printf("NO\n"); } } return 0; }
hdu2289 Cup
还是用二分解的。
需要先计算公式:
设h为水的高度
水的上表面圆半径a=h*(r-R)/H+r
水的下表面高度为r
水的体积为v=PI*(r*r+r*a+a*a)*h/V.
然后,就是纯纯的二分啦,注意精度,WA了很多次、、、、
#include <iostream> #include<stdio.h> #include<cmath> using namespace std; #define INF 0.00000001 const double PI = acos(-1.0); double R,r,H,V; double fun(double h) { double a=h*(R-r)/H+r; return PI*(r*r+r*a+a*a)*h/3.0; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%lf%lf%lf%lf",&r,&R,&H,&V); double first=0;double end=H; double mid=0; while((end-first)>INF) { mid=(first+end)/2.0; double res=fun(mid); if(res>V) end=mid+0.000000001; else if(fabs(res-V)<INF) break; else first=mid-0.000000001; } printf("%.6lf\n",mid); } return 0; }