题解:P2281 [HNOI2003] 多项式的加法和乘法

· · 题解

求求 NOIP 出题人,如果要出字符串大模拟,善待我一些吧/kel

用一个结构体封装单项式,一个结构体封装多项式。

单项式中要用到的东西:

多项式中要用到的东西:

下面是每个函数的具体坑点:

单项式:

多项式:

想不到别的坑点了。

Code

#include<bits/stdc++.h>
#define int long long
#define pb emplace_back
#define Fr(i,il,ir) for(int i=(il);i<(ir);++i)
using namespace std;

struct mono{
    int v,a[26];
    mono(){ v=0;memset(a,0,sizeof(a)); }
    bool operator < (mono rc)const{ if(!v||!rc.v) return v<rc.v; Fr(i,0,26) if(a[i]!=rc.a[i]) return a[i]<rc.a[i];return 0; }
    bool operator == (mono rc)const{ if(!v||!rc.v) return v==rc.v; Fr(i,0,26) if(a[i]!=rc.a[i]) return 0; return 1; }
    mono operator * (mono rc)const{ mono res;res.v=v*rc.v; Fr(i,0,26) res.a[i]=a[i]+rc.a[i]; return res; }
    void printmono(){//输出单项式
        if(abs(v)!=1) printf("%lld",v);
        if(v==-1) putchar('-'),v=1;
        bool printflag=false;
        Fr(i,0,26) if(a[i]){
            printflag=true,putchar('A'+i);
            if(a[i]!=1) printf("^%lld",a[i]);
        }
        if(!printflag&&v==1) printf("%lld",v);
    }
};
mono getmo(string s)//获取单项式
{
    mono ret;int len=s.size();
    //获取系数
    int i,x=0,f=1;bool flag=false;
    for(i=0;i<len&&!isupper(s[i]);i++)
        if(s[i]=='-') f=-f;
        else if(isdigit(s[i])) x=x*10+(s[i]^48),flag=true; 
    ret.v=flag?x*f:f;
    //指数累加
    int nw=-1;x=0,f=1,flag=false;
    for(;i<len;++i)
        if(isupper(s[i])){
            if(~nw) ret.a[nw]+=flag?x*f:f;
            nw=s[i]-'A',x=0,f=1,flag=false;
        }
        else if(s[i]=='^') flag=true;
        else if(s[i]=='-') f=-f;
        else if(isdigit(s[i])) x=x*10+(s[i]^48);
    if(~nw) ret.a[nw]+=flag?x*f:f;
    return ret;
}
struct polyno{
    vector<mono> ve;
    void unique()
    {
        if(!ve.size()) return;
        sort(ve.begin(),ve.end());int tot=-1;
        for(auto x:ve) if(x.v)
            if(~tot&&x==ve[tot]) ve[tot].v+=x.v;
            else ve[++tot]=x;
        ve.resize(tot+1);
    }
    void getpoly(){//获取多项式
        string s,t="";getline(cin,s);
        s=" "+s+" ";int len=s.size();//为了循环中 i-1 和 i+1 不越界,前后各加一个空格。
        Fr(i,0,len)//分割成单项式(string t)加进去
            if((s[i]=='+'||s[i]=='-')&&s[i-1]==' '&&s[i+1]==' '){
                if(t!="") ve.pb(getmo(t)),t="";
                if(s[i]=='-') t=t+s[i];
            }else if(s[i]!=' ') t=t+s[i];
        if(t!="") ve.pb(getmo(t));
        unique();
    }
    polyno operator + (polyno rc)const{
        polyno res;
        for(auto x:ve) res.ve.pb(x);
        for(auto x:rc.ve) res.ve.pb(x);
        res.unique();return res;
    }
    polyno operator * (polyno rc)const{
        polyno res;
        for(auto x:ve) for(auto y:rc.ve) res.ve.pb(x*y);
        res.unique();return res;
    }
    void print(){//多项式输出
        unique();
        if(!ve.size()){ puts("0"); return; }
        Fr(i,0,ve.size()){
            if(i&&ve[i].v>=0) putchar('+');
            ve[i].printmono();
        }putchar('\n');
    }
}A,B,C,D;
signed main(){
    A.getpoly();B.getpoly();
    C=A+B,D=A*B;C.print(),D.print();
    return 0;
}