hdu3336
http://acm.hdu.edu.cn/showproblem.php?pid=3336
这道题是水题,但是我超时了三次才过。而我队友是水过的,这个问题值得我反思。以前,对于ac过的题目,我一般是不会再回去看代码的,因为我觉得可以用更多时间来做下一道题目,而我队友不这样认为,他对他的代码和算法在时间复杂度上要求高。他会一题多做几遍,尽量缩减他代码的时间复杂度。以前一道题目,我们两的思路是一样的,但是我的代码超时了,而他过了,那次我并没有多重视,现在这样的情况再次出现了,我想我自己也必须重视自己代码的时间复杂度了,尽量精益求精,将代码中那些不必要花费的时间都精简一遍,这也是对自己代码和思维的严格要求。一题至少要对写的代码优化一遍...................
#include<iostream> using namespace std; int a[200005]; char s[200005],t[200005]; int main() { int f; scanf("%d",&f); while(f--) { int n,i,j,sum=0; scanf("%d",&n); scanf("%s",s); t[0]=s[0]; j=0; for(i=0;i<n;i++) { if(s[i]==t[0]) { a[j++]=i; sum++; } } int m=1,count=1,h=0,tmp=0,b[200005]; while(m<n) { tmp=0; t[m]=s[m]; //这里是重点,因为它是一个个字符慢慢递增上去的 for(i=0;i<j;i++) { h=0; int w=0; if(a[i]+m<n&&s[a[i]+m]==t[m]) //同理,这里也是 w=1; if(w==1) { sum++; sum%=10007; //printf("\n%d\n",a[i]); b[tmp++]=a[i]; } } for(int y=0;y<tmp;y++) //记录下一次要比较的位置 { a[y]=b[y]; } j=tmp; m++; //printf("\n%d\n",tmp); } printf("%d\n",sum%10007); } return 0; }
上面的代码是46ms过的,下面这代码是31ms过的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 using namespace std; 3 int a[200005]; 4 char s[200005],t[200005]; 5 int main() 6 { 7 int f; 8 scanf("%d",&f); 9 while(f--) 10 { 11 int n,i,j,sum=0; 12 scanf("%d",&n); 13 scanf("%s",s); 14 t[0]=s[0]; 15 j=0; 16 for(i=0;i<n;i++) 17 { 18 if(s[i]==t[0]) 19 { 20 a[j++]=i; 21 sum++; 22 } 23 } 24 int m=1,count=1,h=0,tmp=0,b[200005]; 25 while(m<n) 26 { 27 tmp=0; 28 t[m]=s[m]; //这里是重点,因为它是一个个字符慢慢递增上去的 29 h=0; 30 for(i=0;i<j;i++) 31 { 32 int w=0; 33 if(a[i]+m<n&&s[a[i]+m]==t[m]) //同理,这里也是 34 w=1; 35 if(w==1) 36 { 37 sum++; 38 sum%=10007; 39 //printf("\n%d\n",a[i]); 40 b[tmp]=a[i]; 41 a[h++]=b[tmp++]; 42 43 } 44 } 45 j=tmp; 46 m++; 47 //printf("\n%d\n",tmp); 48 } 49 printf("%d\n",sum%10007); 50 } 51 return 0; 52 }
继续将空间复杂度优化了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 using namespace std; 3 int a[200005]; 4 char s[200005],t[200005]; 5 int main() 6 { 7 int f; 8 scanf("%d",&f); 9 while(f--) 10 { 11 int n,i,j,sum=0; 12 scanf("%d",&n); 13 scanf("%s",s); 14 t[0]=s[0]; 15 j=0; 16 for(i=0;i<n;i++) 17 { 18 if(s[i]==t[0]) 19 { 20 a[j++]=i; 21 sum++; 22 } 23 } 24 int m=1,h=0; 25 while(m<n) 26 { 27 t[m]=s[m]; //这里是重点,因为它是一个个字符慢慢递增上去的 28 h=0; 29 for(i=0;i<j;i++) 30 { 31 int w=0; 32 if(a[i]+m<n&&s[a[i]+m]==t[m]) //同理,这里也是 33 w=1; 34 if(w==1) 35 { 36 sum++; 37 sum%=10007; 38 //printf("\n%d\n",a[i]); 39 a[h++]=a[i]; 40 } 41 } 42 j=h; 43 m++; 44 //printf("\n%d\n",tmp); 45 } 46 printf("%d\n",sum%10007); 47 } 48 return 0; 49 }
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。