数组的一个小优化技巧
2009-05-08 05:53 Logic0 阅读(311) 评论(0) 编辑 收藏 举报http://acm.pku.edu.cn/JudgeOnline/problem?id=2443
TLE的代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> bool num[1003][10010]; int main() { int n,m; int i,j,k,tmp,p,q; scanf("%d",&n); for(i=0 ; i<n ; i++) { scanf("%d",&m); for(j=0 ; j<m ; j++) { scanf("%d",&tmp); num[i][tmp] = 1; } } scanf("%d",&m); for(p=0 ; p<m ; p++) { scanf("%d%d",&i,&j); for(q=0 ; q<n ; q++) { if(num[q][i] && num[q][j]) { printf("Yes\n"); break; } } if(q==n) { printf("No\n"); } } return 0; }
AC的代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> bool c[10010][1010]; int main() { int n,m,t,i,j,a,temp,g,k; bool flag; memset(c,false,sizeof(c)); scanf("%d",&n); for(t=1;t<=n;t++) { scanf("%d",&m); while(m--) { scanf("%d",&temp); c[temp][t]=true; } } scanf("%d",&k); while(k--) { scanf("%d%d",&i,&j); flag=true; for(g=1;g<=n;g++) { if(c[i][g]&&c[j][g]) { printf("Yes\n"); flag=false; break; } } if(flag) printf("No\n"); } return 0; } 唯一的区别就在于数组的维数上:b[1003][10010] 这样定义的时候是超时的。b[10010][1003] 这样定义的时候是可以AC的。具体区别正在研究中//2009-5-8补充原因:数据寻址的过程不同。数组在intel机中是按行存储,每次将二维数组行地址放入基址寄存器,然后找到数据地址。对于b[1003][10010],执行下列代码:for(p=0 ; p<n ; p++){if(b[i][p] && b[j][p])}只需将行地址b[i]和b[j]存储即可,然后在以此行地址为首地址的一维数组内寻找数据。而另外的方法则是每次都要重新计算行的首地址,并将其存入基址寄存器,再计算数据位置,相比来看操作要多于前者,在数据量大的时候就显现出其差别。总结:在定义数组的时候,如果可以,尽量将第一维设置为较小的。