多项式加法和乘法
- 多项式的加法
- 题目描述
- 输入输出
- 样例
- 步骤
- 代码段
- 全局变量设定
- 新建结点
- 合并链表
- 完整代码
- 多项式乘法
- 题目描述
- 输入输出
- 样例
- 代码段
- 计算两多项式结果
- 输入
- 完整代码
多项式的加法
题目描述
输入输出
样例
步骤
总体思想是用链表来做
① 我们发现输入样例中,系数和指数是分开输入的。也就是说,输入系数的时候,我们并不知道他对应的指数是多少。因此,我们先定义一个两个数组,一个放系数,一个放指数,然后转换为结点(用结构体,存放每一项的系数和指数),放进链表。
②输入第二个多项式的时候,要在合适的地方插入链表
- 如果遍历到指数相同的节点,则指数相加,不建立新的节点
- 如果遍历到第一个指数比自己大的节点,则插入到这个节点之前
- 如果直接遍历到链表尾端了,那就插在最后
代码段
全局变量设定
typedef struct node{//存放系数和指数ll ind;ll exp;struct node* next;
}NODE;
NODE* head;//合并之后链表的头结点
int n,m;//多项式1和2的长度
ll ret;//记录系数非零的节点数目
注意一点,因为是多组数据输入,因此每一次都要确保全局变量ret清零
新建结点
NODE* createNode(ll i,ll e){NODE* newnode = (NODE*)malloc(sizeof(NODE));newnode->ind=i;newnode->exp=e;newnode->next=NULL;return newnode;
}
用于合并两个链表时使用
合并链表
合并两个有序链表是非常经典的链表算法,这里我传的参数并不是链表,但是也是用到了合并链表的思想
void merge(ll* ind1,ll*exp1,ll*ind2,ll*exp2){NODE* tail = head;int i1 =0;int i2=0;//i1和i2分别记录两个多项式的当前最后一位while(i1!=n&&i2!=m){if(exp1[i1]>exp2[i2]){NODE* new = createNode(ind2[i2],exp2[i2]);tail->next = new;i2++;}else if(exp1[i1]<exp2[i2]){NODE* new = createNode(ind1[i1],exp1[i1]);tail->next = new;i1++;}else{NODE* new = createNode(ind1[i1]+ind2[i2],exp1[i1]);tail->next = new;i1++;i2++;}tail=tail->next;ret++;}while(i1!=n){NODE* new = createNode(ind1[i1],exp1[i1]);tail->next = new;i1++;ret++;tail=tail->next;}while(i2!=m){NODE* new = createNode(ind2[i2],exp2[i2]);tail->next = new;i2++;ret++;tail=tail->next;}
}
完整代码
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<stdbool.h>
#include<time.h>
#include<limits.h>
typedef long long ll;
#define MAX_N 100005
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
typedef struct node{//存放系数和指数ll ind;ll exp;struct node* next;
}NODE;
NODE* head;
int n,m;
ll ret;//记录系数非零的节点数目
NODE* createNode(ll i,ll e){NODE* newnode = (NODE*)malloc(sizeof(NODE));newnode->ind=i;newnode->exp=e;newnode->next=NULL;return newnode;
}
void merge(ll* ind1,ll*exp1,ll*ind2,ll*exp2){NODE* tail = head;int i1 =0;int i2=0;//i1和i2分别记录两个多项式的当前最后一位while(i1!=n&&i2!=m){if(exp1[i1]>exp2[i2]){NODE* new = createNode(ind2[i2],exp2[i2]);tail->next = new;i2++;}else if(exp1[i1]<exp2[i2]){NODE* new = createNode(ind1[i1],exp1[i1]);tail->next = new;i1++;}else{NODE* new = createNode(ind1[i1]+ind2[i2],exp1[i1]);tail->next = new;i1++;i2++;}tail=tail->next;ret++;}while(i1!=n){NODE* new = createNode(ind1[i1],exp1[i1]);tail->next = new;i1++;ret++;tail=tail->next;}while(i2!=m){NODE* new = createNode(ind2[i2],exp2[i2]);tail->next = new;i2++;ret++;tail=tail->next;}
}
int main(){//初始化链表头结点,作为哑结点head =(NODE*)malloc(sizeof(NODE));head->ind=head->exp=-1;head->next=NULL;int t;scanf("%d",&t);while(t--){ret=0;scanf("%d",&n);ll arr1_ind[n];//存放第一个多项式的系数for(int i=0;i<n;i++){scanf("%lld",&arr1_ind[i]);}ll arr1_exp[n];//存放第一个多项式的指数for(int i=0;i<n;i++){scanf("%lld",&arr1_exp[i]);}scanf("%d",&m);ll arr2_ind[m];//存放第二个多项式的系数for(int i=0;i<m;i++){scanf("%lld",&arr2_ind[i]);}ll arr2_exp[m];//存放第二个多项式的指数for(int i=0;i<m;i++){scanf("%lld",&arr2_exp[i]);}//合并两个多项式merge(arr1_ind,arr1_exp,arr2_ind,arr2_exp);//输出最后合并的结果printf("%lld\n",ret);NODE* cur = head->next;while(cur!=NULL){printf("%lld ",cur->ind);cur = cur->next;}printf("\n");cur = head->next;while(cur!=NULL){printf("%lld ",cur->exp);cur = cur->next;}printf("\n");}return 0;
}
多项式乘法
题目描述
输入输出
样例
代码段
计算两多项式结果
ll cal(ll base1,ll base2,ll* a,ll* b){ll ret1 = 0;ll x=1;for(int i=0;i<=n;i++){ret1=(ret1%MOD+x*a[i]%MOD)%MOD;x=(x*base1)%MOD;}ll ret2 = 0;x=1;for(int i=0;i<=m;i++){ret2=(ret2%MOD+x*b[i]%MOD)%MOD;x=(x*base2)%MOD;}return (ret1*ret2)%MOD;
}
注意取模的规则
输入
cin>>n;ll a[n+1];//注意要多开辟一个空间for(int i=0;i<=n;i++){cin>>a[i];}cin>>m;ll b[m+1];for(int i=0;i<=m;i++){cin>>b[i];}
两个系数数组都要记得多开辟一个空间,因为n和m代表最高次数,1-n次再加上一个0次,一共需要n+1个空间
完整代码
#include <iostream>
using namespace std;
#define MOD 10007
typedef long long ll;
int n,m,q;
ll cal(ll base1,ll base2,ll* a,ll* b){ll ret1 = 0;ll x=1;for(int i=0;i<=n;i++){ret1=(ret1%MOD+x*a[i]%MOD)%MOD;x=(x*base1)%MOD;}ll ret2 = 0;x=1;for(int i=0;i<=m;i++){ret2=(ret2%MOD+x*b[i]%MOD)%MOD;x=(x*base2)%MOD;}return (ret1*ret2)%MOD;
}
int main(){cin>>n;ll a[n+1];for(int i=0;i<=n;i++){cin>>a[i];}cin>>m;ll b[m+1];for(int i=0;i<=m;i++){cin>>b[i];}cin>>q;for(int i=0;i<q;i++){ll base1,base2;cin>>base1>>base2;cout<<cal(base1,base2,a,b)<<endl;}
}