POJ 3727 Newton’s Method

这道题是我的第400道题,并不难,就是考虑的时候稍微有点繁琐,想想自己做的那400道题,几乎都是水题,很多都是在discuss的提醒下AC的,并没有什么技术含量,很多的时候都是为了刷足题数而做的,自己想的很少,收获的也很少,除了看到题目能初步地判断是什么类型的题之外几乎没有什么提高,一直在浑浑噩噩的刷题却没有去考虑一些本质性的东西。

额,扯远了,这道题就是在将字符串转化为多项式每一项的系数和指数这个过程稍微有点麻烦,根据题目我们可以发现多项式的每一项都是"ax^b "这种形式,而且后面肯定有空格,那就可以根据空格来判断多项式每一项的结尾,读进去之后带入公式就行了,给组discuss的测试数据:

Input:

x +3 = 0
2
-x +3 = 0
-2
3 +x = 0
2
3 -x = 0
-2
x^2 +2x +1 = 0
2
x^2 -2x +1 = 0
2
x^2 -2x +1 = 0
1
x^2 -2x +1 = 0
-1
-22x^3 +10x^2 -11x^-3 -4 = 0
33
3x -23 +x^2 = 0
3
-3x^2 -3 = 0
3
3x -3 = 0
1
5x^2 -2 = 0
-5
23x^3 +3x^2 -4x +2 = 0
5
x^2 -1 = 0
2
-x^2 +1 = 0
2
23x^5 +34x^3 -34x^2 +3 = 0
34
-23x^3 +34x^2 -34x^-3 -4 = 0
-34
3x^2 +32 -5x^2 +3x^3 +2x = 0
2
6x +32x -5x^3 -7x^3 +31 -4 = 0
3

Output:

1
1
1
1
12
10
0
11
Bad x0 or bad equation!
3
Bad x0 or bad equation!
0
6
26
4
4
22
Bad x0 or bad equation!
11
4
代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
double eps=1e-6;
char s[2000];						//读入的字符串
int s1[1000];						//用来保存系数
int s2[1000];						//用来保存指数
int top;							//表示总数
void arr()
{
	int i,tmp=0,zhishu,xishu;		//tmp储存当前值,zhishu存储指数,xishu存储系数
	bool fu=0,zs=0,xs=0;			//表示是否有负数,指数和系数
	for(i=0;i<strlen(s);i++)
	{
		if(s[i]=='=')
			break;
		if(s[i]>='0' && s[i]<='9')	//改变当前值
			tmp=tmp*10+s[i]-'0';
		if(s[i]=='-')				//记录负数
			fu=1;
		if(s[i]=='^')				//表明有指数
		{
			tmp=0;
			zs=1;
		}
		if(s[i]=='x')				//表明系数的结束
		{
			if(tmp==0)	tmp=1;
			xishu=tmp;
			if(fu)
				xishu=-xishu;
			fu=0;
			tmp=0;
			xs=1;
		}
		if(s[i]==' ')				//表明已经读入一组系数和指数
		{
			if(zs && xs)
			{
				zhishu=tmp;
				if(fu) zhishu=-zhishu;
			}
			else if(!zs && xs)
				zhishu=1;
			else
			{
				xishu=tmp;
				if(fu)
					xishu=-xishu;
				zhishu=0;
			}
			s1[top]=xishu;
			s2[top++]=zhishu;
			zs=0;
			xs=0;
			fu=0;
			zhishu=xishu=tmp=0;
		}
	}
}
double abs(double n)
{
	if(n<0)
		return -n;
	return n;
}
double f1(double x)								//求f(x)
{
	int i;
	double sum=0;
	for(i=0;i<top;i++)
		sum+=pow(x,(double)s2[i])*(double)s1[i];
	return sum;
}
double f2(double x)								//求f'(x)
{
	int i;
	double sum=0;
	for(i=0;i<top;i++)
		if(s2[i])
			sum+=pow(x,(double)s2[i]-1)*(double)s1[i]*s2[i];
	return sum;
}
int solve(double x)								//辗转求解,找不到就返回一个比1000大的数
{
	double ff1,ff2;
	double y;
	int cnt=0;
	while(1)
	{
		ff1=f1(x),ff2=f2(x);
		y=x-ff1/ff2;
		if(abs(x-y)<eps || abs(ff1)<eps || cnt>=1002)
			break;
		x=y;
		cnt++;
	}
	return cnt;
}
int main()
{
	double n;
	int i;
	//freopen("a.a","r",stdin);
	//freopen("b.a","w",stdout);
	while(gets(s))
	{
		top=0;
		scanf("%lf",&n);
		arr();
		int cnt=solve(n);
		if(cnt>1000)
			printf("Bad x0 or bad equation!\n");
		else
			printf("%d\n",cnt);
		getchar();
	}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值