2021-02-26-PAT-B1030 完美数列 (25 分)(思路)

PAT-B1030 完美数列 (25 分)(思路)

  1. 题意:给出n个数,在这n个数中找出一个长度最长的序列,要求在这个序列中,最大数字小于等于最小数字*参数P。求序列最长长度
  2. 思路:刚明白题意的时候感觉题目好复杂,不知道用什么算法去写,直接参考csdn上的的博客,明白了需要用到双重循环,同时复杂的问题一下子清晰明了了。
  3. step1:对读入数据,并从小到大排序。
  4. step2:首先设置最终得到的序列长度为mmax=0(由此记录循环过程中得到的最大的序列长度);接下去用两个循环来求解。
  5. step3:第一层(for i=0;i<n;i++)这里的i为最小数的下标的索引。第二层for(j=i+mmax;j<n;j++)这里的j为此时遍历到的最大的数的下标索引,当满足a[i]*p>=a[j]时,就可以让mmax=j-i+1;不满足时,跳出j循环。就这样,一直遍历下去,因为mmax一直保存的是已经求出的最大的长度,因此循环过程中的逻辑一直是正确的,一般循环到j<n之后就可以得出结果了。
  6. step4:给一组数据可以模拟一下:2 3 20 4 5 1 6 7 8 9 20 50 80 100 300 500
    OK!思路写完了,去写代码~
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    
    
    ll n,p;//注意要用long long类型,因为p*a[i]运算过程中可能会超10^9;
    cin>>n>>p;
    ll a[100010];
    for(int i=0;i<n;i++)
        scanf("%lld",&a[i]);
    sort(a,a+n);
    ll mmax=0;//首先设置求得的最长序列长度为0;
    for(int i=0;i<n;i++)//最小数下标
    {
    
    
        for(int j=mmax+i;j<n;j++)//j=mmax+1我觉得是整个算法的核心,就是如果遇到不满足a[i]*p>=a[j]时,break后进入i+1之后的循环
        {
    
    							//进入i+1之后的循环后j同样随着mmax+1也加了1,最大元素指向了刚刚不满足条件的下一个,好经典
            if(a[j]<=a[i]*p)
                mmax=j-i+1;
            else
                break;//a[j]不满足,那其之后的数都不满足,直接break。
        }
    }
    printf("%lld",mmax);
}

思路参考第二个

猜你喜欢

转载自blog.csdn.net/CSDN_Ysu/article/details/114141961