hdu-2199、hdu2899、hdu2141、hdu2289二分,牛顿迭代

额、、、、第一次解高次方程,吓着自己了。看了很多资料(跑偏了,找各种数学公式去了、、、、正在筹备总结学过的各种数论知识点)。加油!!!吖飒~~~~

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;
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值