1.解题思路
前面模拟部分不难,用flag标记上一字符为大写/小写/数字,逐个遍历字符将对应值/切换值压入临时数组tmp,填充成偶数再两两一组运算,到这可以拿40分,难点是多项式除法,x^k相当于将d(x)提升k位,x^k * d(x)作为被除数,g(x)作为除数,q(x)相当于商 r(x)相当于余数,每次除法消掉了被除数的最高位,即每一次运算都取当前结果最高项的系数除以除数最高项的系数。
但是被自己蠢到了,居然搞错了输出格式。。。。下次一定要注意看输出格式!!
2.满分代码
#include<iostream>
#include<vector>
#include<math.h>
using namespace std;
const int mod=929;
const int N=1e6+6;
int g[N],d[N];
int main()
{
int w,s;
string str;
cin>>w>>s;
cin>>str;
int k=(s==-1)?0:(pow(2,s+1));
vector<int>tmp,ans;
int len=str.size();
int flag=1;//1--大写 2--小写 3--数字
for(int i=0;i<len;i++)
{
if(str[i]>='A'&&str[i]<='Z')
{
if(flag==2)
{
tmp.push_back(28);
tmp.push_back(28);
}
else if(flag==3)
{
tmp.push_back(28);
}
tmp.push_back(str[i]-'A');
flag=1;
}
else if(str[i]>='a'&&str[i]<='z')
{
if(flag==1)
{
tmp.push_back(27);
}
else if(flag==3)
{
tmp.push_back(27);
}
tmp.push_back(str[i]-'a');
flag=2;
}
else if(str[i]>='0'&&str[i]<='9')
{
if(flag==1)
{
tmp.push_back(28);
}
else if(flag==2)
{
tmp.push_back(28);
}
tmp.push_back(str[i]-'0');
flag=3;
}
}
if(tmp.size()%2)tmp.push_back(29);
for(int i=0;i<tmp.size();i+=2)
{
ans.push_back(30*tmp[i]+tmp[i+1]);
}
int l=1+ans.size()+k;
if(l%w!=0)
{
for(int i=0;i<w-l%w;i++)
{
ans.push_back(900);
}
}
int r=ans.size();
int n=1+r;
//计算gx
g[0]=1;
int a=-3;
for(int i=1;i<=k;i++)
{
for(int j=i-1;j>=0;j--)
{
g[j+1]=(g[j+1]+g[j]*a)%mod;
}
a=(a*3)%mod;
}
for(int i=1;i<=r;i++)
{
d[i]=ans[i-1];
}
d[0]=n;
//计算dx
for(int i=0;i<=r;i++)
{
int x=d[i];
d[i]=0;
for(int j=1;j<=k;j++)
{
d[i+j]=(d[i+j]-x*g[j])%mod;
}
}
//输出
cout<<n<<endl;
for(int i=0;i<r;i++)
{
cout<<ans[i]<<endl;
}
for(int i=r+1;i<=r+k;i++)
{
cout<<((-d[i]%mod)+mod)%mod<<endl;
}
return 0;
}