多项式相加

【题目描述】给出两个多项式,求它们的和

【输入】分别给出两个多项式,每个多项式给出的方式为多组输入。每行给出两个整数a,b表示ax^b,直至输入0 0结束。(可以直接参照样例)

【输出】编写提示信息,每个多项式输入完成后立即输出该多项式的表示,两个多项式都输入完成后,输出两个多项式的和。(描述不够细致可直接参照样例)

【样例】 

输入:

8 5
-2 3
0 0

1 2
3 4
4 3
-3 3
3 0
0 0

输出:

请输入第一个多项式的系数和指数,以(0,0)结束:
请输入系数和指数(如:"2 3"表示2x^3):8 5
请输入系数和指数:-2 3
请输入系数和指数:0 0
第一个多项式输出如下:
8x^5-2x^3
请输入第二个多项式的系数和指数,以(0,0)结束:
请输入系数和指数(如:"2 3"表示2x^3):
1 2
请输入系数和指数:3 4
请输入系数和指数:4 3
请输入系数和指数:-3 3
请输入系数和指数:3 0
请输入系数和指数:0 0
第二个多项式输出如下:
3x^4+x^3+x^2+3
8x^5+3x^4-x^3+x^2+3

【分析】题目难度不大,主要是坑比较多,思考量比较多。主要的难度点在于多项式的表示以及多项式相加的combine()函数的编写(本质是链表的合并)。链表的基本操作是基础,因为多项式的指数可以是不连续的而且可以很大。理论上开个较大的数组用计数排序的思想也是可行的,但是指数一大就太耗费空间了,而且还要考虑到用二维数组存储系数,所以选择用链表。

思维量集中在多项式的表示,所以在做这道题之前,我先去过了下noi的1.13的第39题,题目如下:​​​​

描述

一元 n 次多项式可用如下的表达式表示:

f(x)=anxn+an-1xn-1+...+a1x+a0,an≠0

其中,aixi称为i次项,ai称为i次项的系数。给出一个一元多项式各项的次数和系数,请按照如下规定的格式要求输出该多项式:

1. 多项式中自变量为x,从左到右按照次数递减顺序给出多项式。

2. 多项式中只包含系数不为0的项。

3. 如果多项式n次项系数为正,则多项式开头不出现“+”号,如果多项式n次项系数为负,则多项式以“-”号开头。

4. 对于不是最高次的项,以“+”号或者“-”号连接此项与前一项,分别表示此项系数为正或者系数为负。紧跟一个正整数,表示此项系数的绝对值(如果一个高于0次的项,其系数的绝对值为1,则无需输出1)。如果x的指数大于1,则接下来紧跟的指数部分的形式为“x^b”,其中b为x的指数;如果x的指数为1,则接下来紧跟的指数部分形式为“x”; 如果x的指数为0,则仅需输出系数即可。

5. 多项式中,多项式的开头、结尾不含多余的空格。

输入

共有2 行:
第一行 1 个整数 n,表示一元多项式的次数。
第二行有 n+1 个整数,其中第 i 个整数表示第 n-i+1 次项的系数,每两个整数之间用空格隔开。

1 ≤ n ≤ 100,多项式各次项系数的绝对值均不超过100。

输出

共1行,按题目所述格式输出多项式。

样例输入

样例 #1:
5
100 -1 1 -3 0 10

样例 #2:
3
-50 0 0 1

样例输出

样例 #1:
100x^5-x^4+x^3-3x^2+10

样例 #2:
-50x^3+1

链接在这:http://noi.openjudge.cn/ch0113/solution/35197972/

下面是我通过的代码:

#include <stdio.h>

int main() {
	int n,m;
	scanf("%d",&n);
	int flag = 1; 
	for(int i=n;i>=0;i--) {
		scanf("%d",&m);
		if(m==0) continue; //系数为0直接跳过 
		if(i==n) { //多项式的最高项 
			if(m==-1) printf("-"); //系数是-1的输出负号 
			else if(m!=1) printf("%d",m); //其他情况只要不是1都原样输出 
		}else if(i==0) { //多项式的最低项 
			if(m==1) printf("+1");
			else if(m==-1) printf("-1");
			else if(m>0 && !flag) printf("+%d",m);
			else if(m>0 && flag) printf("%d",m);
			else if(m<0) printf("%d",m);
			break; //直接跳出循环
		}else {
			if(m==-1) printf("-"); //系数是-1的输出负号 
			else if(m==1) printf("+"); //系数是1的输出正号
			else if(m<0) printf("%d",m); //其他情况是负数就原样输出 
			else if(m>0) printf("+%d",m); //是正数数就加正号后输出  
		}
		if(i==1) printf("x"); //特判指数为1输出x
		else if(i!=0) printf("x^%d",i);//指数不为0就原样输出 
		flag = 0;
	}
	return 0;
}

我认为这道题有个地方出的不好,我第一遍提交的代码当输入为1 0 2是输出结果为+2是可以accepted的。上面的代码是处理过后第二次提交的代码,输出为2,也是可以通过的。

最后直接上多项式相加的代码,细节都在代码里啦:

#include <stdio.h>
#include <stdlib.h>

typedef struct polynomial {
	int coefficient;
	int exp;
	struct polynomial * next;
}NODE, *PNODE;

void insert(PNODE L, int coefficient, int exp) {
	PNODE s = (NODE*)malloc(sizeof(NODE));
	s->coefficient = coefficient;
	s->exp = exp;
	s->next = NULL;
	PNODE p = L->next, q = L;
	while(p && p->exp > exp) { //找到第一个指数不大于插入节点的指数的位置并用p指向它 
		q = p;
		p = p->next;
	}
	if(!p) {	//特判p是否为空,即插入在最后的情况 
		q->next = s;
		return;
	}
	if(p->exp == exp) {	 //讨论指数等于p指向节点的指数还是小于p指向节点的指数分别处理 
		p->coefficient += coefficient;
		free(s);
	} else {
		s->next = q->next;
		q->next = s;
	}
}

void input(PNODE &L) {
	L = (NODE*)malloc(sizeof(NODE));
	L->next = NULL;
	int coefficient, exp;
	printf("请输入系数和指数(如:\"2 3\"表示2x^3):");
	scanf("%d%d",&coefficient, &exp);
	insert(L,coefficient,exp);
	while(coefficient || exp) {
		printf("请输入系数和指数:");
		scanf("%d%d",&coefficient, &exp);
		insert(L,coefficient,exp);
	}
}

void print(PNODE L) {
	PNODE p = L;
	int flag = 1;
	while(p) {
		if(p->coefficient==0) {
			p = p->next;
			continue;	
		}
		if(p==L) { //多项式的最高项
			p = L->next;
			if(p->coefficient==-1) printf("-"); //系数是-1的输出负号 
			else if(p->coefficient!=1) printf("%d",p->coefficient); //其他情况只要不是1都原样输出 
		}else if(p->exp==0) { //多项式的最低项 
			if(p->coefficient==1) printf("+1");
			else if(p->coefficient==-1) printf("-1");
			else if(p->coefficient>0 && !flag) printf("+%d",p->coefficient);
			else if(p->coefficient>0 && flag) printf("%d",p->coefficient);
			else if(p->coefficient<0) printf("%d",p->coefficient);
			break; //直接跳出循环
		}else {
			if(p->coefficient==-1) printf("-"); //系数是-1的输出负号 
			else if(p->coefficient==1) printf("+"); //系数是1的输出正号
			else if(p->coefficient<0) printf("%d",p->coefficient); //其他情况是负数就原样输出 
			else if(p->coefficient>0) printf("+%d",p->coefficient); //是正数数就加正号后输出  
		}
		if(p->exp==1) printf("x");
		else if(p->exp) printf("x^%d",p->exp); //指数只要不是0就原样输出
		flag = 0;
		p = p->next;
	}	
	printf("\n");
}

void combine(PNODE &L3, PNODE L1, PNODE L2) {
	L3 = (NODE*)malloc(sizeof(NODE));
	L3->next = NULL;
	PNODE p = L1->next, q = L2->next, r = L3;
	while(p && q) {
		if(p->exp > q->exp) {
			r->next = p;
			p = p->next;
		} else if(q->exp > p->exp) {
			r->next = q;
			q = q->next;
		}else {
			q->coefficient = q->coefficient + p->coefficient;	
			r->next = q;
			q = q->next;
			p = p->next;
		}
		r = r->next;
	}
	r->next = p ? p : q; 
} 

int main() {
	PNODE L1,L2,L3;
	printf("请输入第一个多项式的系数和指数,以(0,0)结束:\n");
	input(L1);
	printf("第一个多项式输出如下:\n");
	print(L1);
	printf("请输入第二个多项式的系数和指数,以(0,0)结束:\n");
	input(L2);
	printf("第二个多项式输出如下:\n");
	print(L2);
	combine(L3,L1,L2);
	print(L3);
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值