1030 完美数列 (25 分)
题目链接:1030 完美数列 (25 分)
未得满分的代码(一个测试点运行超时):
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 long long num[100100]; //此处容易发生段错误 5 int main() 6 { 7 long long n,p,temp; 8 cin>>n>>p; 9 for(int i=0;i<n;i++) 10 scanf("%d",&num[i]); 11 sort(num,num+n); 12 bool flag=false; 13 long long count=n-1; 14 for(;count!=0;count--) 15 { 16 for(int i=0;i+count<n;i++) 17 { 18 if(num[i+count]<=p*num[i]) 19 { 20 flag=true; 21 break; 22 } 23 } 24 if(flag) 25 break; 26 } 27 cout<<count+1<<endl; 28 return 0; 29 } 30 //1 2 3 4 5 6 7 8 9 20
优化后的代码(借鉴网上大佬的):
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 long long num[100100]; //此处容易发生段错误 5 int main() 6 { 7 8 long long n,p,temp; 9 cin>>n>>p; 10 for(int i=0;i<n;i++) 11 scanf("%d",&num[i]); 12 sort(num,num+n); 13 bool flag=false; 14 int count=1; 15 for(int i=0;i<n;i++) //将a[i]作为最小值 16 { 17 for(int j=i+count;j<n;j++) 18 { 19 if(num[j]>num[i]*p) //不满足完美数列 20 break; 21 if(j-i+1>count) //更新最长记录的完美数列长度。 22 count=j-i+1; 23 } 24 } 25 //优化之前的算法运行超时,优化之后的算法AC 26 cout<<count<<endl; 27 return 0; 28 } 29 //1 2 3 4 5 6 7 8 9 20
这道题目的思路:先将题目给定的数列存入数组中,并用sort函数默认排序。
选定一个num[i]作为m(最小值),然后再在i之后选定一个num[j]作为M(最大值),
关于i与j的关系需要仔细考虑(优化时间复杂度的关键)
刚开始我选定j的初值为i+1,即从i后面选定一个肯定比num[i]大的值,然后根据题
目要求进行判断处理。这个思路其实并不难。但是这样编码提交后有一个测试点
超时。借鉴网上大佬的解决办法。解决超时的思路与KMP思想类似。
具体思想是:不做重复工作,让j指针跳过已经比较过的元素。