【2003、2004 NOIp 入门组错题报告】
2003:
T4:
题目大意:
讲这么多话,其实就是求比当前序列大的序列中第m小的一个。可以每次找出比当前序列大的最小的一个序列。我们可以从后往前扫描,当当前这个数比后一个数小时,我们把它与它后面的数中比它大的最小的一个交换,再将它之后的数从小到大排序,
就得到比当前序列大的最小的一个序列了
列: 1 2 3 6 8 7 5 4这个序列,找比它大的最小的序列,我们从后往前扫描,扫到6时发它比它后面一个数8小,我们就将它与它后面比它大的最小的一个数交换,为7,交换后序列为1 2 3 7 8 6 5 4,再将7后的数从小到大排序,变成1 2 3 7 4 5 6 8.
这就是比1 2 3 6 8 7 5 4大的最小的一个序列了。
错题原因:
就拿1 2 3 6 8 7 5 4来说,我只把6加了1,再把它后面最小的数减了1,没考虑后面最小的数可能有比它大2或更多的数;
AC代码:
1 #include<cstdio> 2 #include<algorithm> 3 #include<iostream> 4 using namespace std; 5 6 const int N=10010; 7 8 int n,m; 9 int a[N]; 10 11 int main() 12 { 13 scanf("%d%d",&n,&m); 14 15 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 16 17 while(m--) 18 { 19 int i=n; 20 while(a[i-1]>a[i]) i--; 21 i--; 22 23 int j=i; 24 while(j+1<=n&&a[j+1]>a[i]) j++; 25 swap(a[i],a[j]); 26 27 reverse(a+i+1,a+1+n); 28 } 29 30 for(int i=1;i<=n;i++) 31 { 32 printf("%d ",a[i]); 33 } 34 }
2004:
T1:
题目大意:
根据输入计分。
错题原因:
它要按照标准比赛要求,必须一方分数大于指定分数,两人的分差还得≥2 。你题目又不说,害我只得五十分(╬ ̄皿 ̄) 。
T4:
题目大意:
求 2^p-1 的后500位和它的位数。
错题原因:
位数可以直接用 p㏒102 下取整 +1 求,然而我直接数,超时了。(什么log玄学,不知道!)
AC代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<iostream> 5 using namespace std; 6 7 const int N=10100010; 8 9 int len_a; 10 int res[N],a[N]; 11 int c[N]; 12 13 void mul(int a[],int b[]) 14 { 15 memset(c,0,sizeof(c)); 16 for(int i=1;i<=500;i++) 17 { 18 int t=0; 19 for(int j=1;j<=500;j++) 20 { 21 22 int k=i+j-1; 23 c[k]+=a[i]*b[j]+t; 24 t=c[k]/10; 25 c[k]%=10; 26 27 } 28 29 } 30 31 for(int i=1;i<=500;i++) a[i]=c[i]; 32 33 } 34 35 void qmi(int k) 36 { 37 res[1]=1; 38 a[1]=2; 39 40 while(k) 41 { 42 43 if(k&1) mul(res,a); 44 mul(a,a); 45 k>>=1; 46 } 47 48 res[1]--; 49 printf("%d\n",len_a); 50 for(int i=500,j=1;i;i--,j++) 51 { 52 if(len_a<i) printf("0"); 53 else printf("%d",res[i]); 54 if(j==50) puts(""),j=0; 55 } 56 } 57 58 int main() 59 { 60 int n; 61 scanf("%d",&n); 62 len_a=(int)(n*log10(2))+1; 63 qmi(n); 64 65 }
浙公网安备 33010602011771号