Problem
【题目描述】
给出一个表达式,包含数字、未知数x、“+”、“-”、“*”和括号。把它化简成a0x0+a1x1+a2x2+……+anxn的形式。
【输入格式】
一行一个字符串,即表达式。
【输出格式】
第一行一个非负整数n,接下来n+1个数,其中第i行为ai-1。由于ai可能很大,对10007取模后输出。
若有多个n满足条件,输出最小的n。
【样例输入】
(x-2)*3+x
【样例输出】
1
10001
4
上表中没有填写的格子,表示数据在那一方面没有特殊限制。
保证输入的表达式合法。
保证表达式中出现的数字小于10007。
表达式中没有“6x”这种形式。即数字和未知数之间至少存在一个符号。
栈与多项式加减乘的结合
Code
// by spli
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
const int p=10007;
char s[1010];
int n;
char op[1010];int num;
int st[1010][1010],top;
int tmp[1010],gg[1010];
int fir(char x){// 定义优先级
if(x=='*') return 2;
if(x=='+'||x=='-') return 1;
return 0;
}
void cal(){
if(op[num]=='+'){//多项式加法
for(int i=0;i<=n;++i)
(st[top-1][i]+=st[top][i])%=p;
top--;
}
else if(op[num]=='-'){//多项式减法
for(int i=0;i<=n;++i)
(st[top-1][i]-=st[top][i])%=p;
top--;
}
else if(op[num]=='*'){//多项式乘法
memset(tmp,0,sizeof(tmp));
int c=0;
for(int i=0;i<=n;++i)
if(st[top][i]) gg[++c]=i;
for(int i=0;i<=n;++i)
if(st[top-1][i])
for(int j=1;j<=c;++j)
(tmp[i+gg[j]]+=st[top-1][i]*st[top][gg[j]])%=p;
for(int i=0;i<=n;++i) st[top-1][i]=tmp[i];
top--;
}
num--;
}
int main(){
scanf("%s",s+1);
n=strlen(s+1);
for(int i=1;i<=n;++i){
if(s[i]=='(') op[++num]='(';
else if(s[i]==')'){
while(num>0&&op[num]!='(') cal();
if(op[num]=='(') num--;
}
else if(s[i]=='x'){
memset(st[top+1],0,sizeof(st[top+1]));
st[++top][1]=1;
}
else if(s[i]=='+'||s[i]=='-'){
if(i==1||s[i-1]=='('){
int f=(s[i]=='+'?1:-1);
i++;
if(s[i]=='x'){
memset(st[top+1],0,sizeof(st[top+1]));
st[++top][1]=(1*f%p+p)%p;
continue;
}
else{
int x=s[i]-'0',pos=i+1;
while(s[pos]>='0'&&s[pos]<='9'){
x=x*10+s[pos]-'0';
pos++;
}
i=pos-1;
memset(st[top+1],0,sizeof(st[top+1]));
st[++top][0]=(x*f%p+p)%p;
}
}
else{
while(fir(s[i])<=fir(op[num])) cal();
op[++num]=s[i];
}
}
else if(s[i]>='0'&&s[i]<='9'){
int x=s[i]-'0',pos=i+1;
while(s[pos]>='0'&&s[pos]<='9'){
x=x*10+s[pos]-'0';
pos++;
}
i=pos-1;
memset(st[top+1],0,sizeof(st[top+1]));
st[++top][0]=x;
}
else{
while(fir(s[i])<=fir(op[num])) cal();
op[++num]=s[i];
}
}
while(num) cal();
int ans=0;
for(int i=0;i<=n;++i)
if(st[1][i]) ans=i;
printf("%d\n",ans);
for(int i=0;i<=ans;++i)
printf("%d\n",(st[1][i]%p+p)%p);
return 0;
}