hdu-2199、hdu2899、hdu2141、hdu2289二分,牛顿迭代
2012-03-21 16:13
225 查看
额、、、、第一次解高次方程,吓着自己了。看了很多资料(跑偏了,找各种数学公式去了、、、、正在筹备总结学过的各种数论知识点)。加油!!!吖飒~~~~
hdu2199
题意:
求解8x^4+7x^3+2x^2+3x+6-m=0;这个方程式。
分析:
二分法比较容易。代码比较好写。开始一直觉得二分肯定超时,没敢写代码。后来,写了写才知道直接AC。时间分析,x属于【0-100】,即使是浮点数,也不过多循环几次。二分耗时:log2n,是很小的数。
(警示,一定要论证后,再确定是不是超时。确定思路不会超内存,超时后再去写代码,省去无谓的时间)
代码:
迭代法,还在学习中、、、、稍后更新。
感冒相当严重呀、、、回去睡觉
嘿嘿。。。还是写了写 牛顿迭代,不过可能是精度的问题,数值有点偏大;思想是对的
代码附上:
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带入即可。
代码:
hdu2141 Can you find it?
还是一个二分。稍微有些变形。
先计算好A+B,然后二分查找m-c。
其中 search函数可以写成二分查找的系统函数-binary_search(sum,sum+l*n,x-C[j]);//数组名,数组长度,要查找的数
代码:
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;
}
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;
}
相关文章推荐
- HDU 2199 牛顿迭代
- 09-04 HDU_Steps4.1 二分三分 HDU2199 HDU2899 HDU1967 HDU2141 HDU2298 HDU1597 HDU2438 HDU3400
- HDU 2899 牛顿迭代
- 牛顿迭代公式
- hdu 2199 Can you solve this equation?
- hdu 2199
- (二分) HDU 2199 Can you solve this equation?
- 模拟退火板子 poj1379 hdu 5017 hdu2899
- hdu 2199 Can you solve this equation? 二分
- 用R语言实现牛顿迭代求最优点
- 【HDU】-2199-Can you solve this equation?(二分)
- hdu 5912(迭代+gcd)
- HDU 1560 迭代加深 解题报告
- HDU—2199—Can you solve this equation?—【二分】【精度控制】
- HDU 2199 Can you solve this equation(二分水题)
- C#---最速下降+牛顿迭代求二元非线性方程组
- HDU - 2199
- hdu-2199 Can you solve this equation?(二分+精度)
- HDU 2199
- HDU 2199 Can you solve this equation?