题意:给出N,A,计算i*A^i(i=1~N)的和。1<=N<=30,0<=A<=15。
就是大数据运算,别的没什么,注意细节之处即可。
这题还要注意两个地方:
1.考虑A=0的情况,直接输出0即可。(我没写这个判断时,竟给我RE,而不是WA。。。不知道RE出在哪里了)
2.计算A^i的值的时候,不要每次都重新计算,会超时。后一次A^(i+1)可以利用前一次A^i的结果,乘以A即可。
#include <iostream> #include <string.h> #include <stdio.h> #include <string> #include <string.h> using namespace std; int N,A; int n1,n2,n3;//n1表示a的位数,n2表示b的位数,n3表示c的位数 int a[10],b[10],c[200]; //a存储A的值,b存储N的值,c存储A^i的值 int ans[200],tmp[200]; //ans存储最后的结果 void add(int b[]) { for(int i=0; i<200; i++) { ans[i]=ans[i]+b[i]; if(ans[i]>9) { ans[i]-=10; ans[i+1]++; } } } int multiply(int a1[],int b1[],int n1,int n2) { memset(tmp,0,sizeof(tmp)); for(int i=0; i<n1; i++) { for(int j=0; j<n2; j++) { tmp[i+j]+=a1[i]*b1[j]; } } for(int i=0; i<n1+n2; i++) { if(tmp[i]>=10) { tmp[i+1]+=tmp[i]/10; tmp[i]%=10; } } /* for(int i=0; i<n1+n2; i++) c[i]=tmp[i]; */ //第n1+n2位的序号为n1+n2-1,一开始就直接写了c[n1+n2]>0,结果就错了 if(tmp[n1+n2-1]>0) return n1+n2; else return n1+n2-1; } int main() { while(scanf("%d%d",&N,&A)!=EOF) { memset(ans,0,sizeof(ans)); //不写下面A=0的情况,会RE,但具体RE出在哪里就不知道了 if(A==0) { printf("0 "); continue; } if(A<10) n2=1; else n2=2; a[0]=A%10; a[1]=A/10; memset(c,0,sizeof(c)); c[0]=1; n1=1; //不需要每次都重新计算A^i的值(不然会超时),后一次A^(i+1)可以利用前一次A^i的结果,每次计算的值存储在c数组里 for(int i=1; i<=N; i++) { n1=multiply(c,a,n1,n2); //将乘后的结果存入到c数组,以便后一次利用 for(int j=0; j<n1+n2; j++) c[j]=tmp[j]; b[0]=i%10; b[1]=(i/10)%10; b[2]=i/100; if(i<10) n3=1; else if(i<100) n3=2; else n3=3; //每次循环i*A^i的值存储在tmp数组里后,再与ans相加存储到ans数组中 multiply(c,b,n1,n3); add(tmp); } //找到ans中最高位的索引 int idx=199; while(1) { if(ans[idx]==0) { idx--; continue; } else break; } for(int i=idx; i>=0; i--) { printf("%d",ans[i]); } printf(" "); } return 0; }