PAT basic level 1030完美数列

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int N, p;
    cin >> N >> p;
    vector<int> v(N);
    for (int i = 0; i < N; i++)
    {
        cin >> v[i];
    }
    sort(v.begin(), v.end());
    int maxCount = 1;  // 记录满足条件的最大数量
    for (int left = 0; left < N; left++) {
        int right = left + maxCount;  // 右指针位置
        if (right >= N) {
            break;  // 右指针越界,结束循环。注意!这一步很容易被忽视
        }
        while (right < N && v[right] <= (long long)v[left] * p) {    //这里的(long long)是最后的陷阱,因为int的数据容量是2的32次(或31次)-1,也就是4294967295(或2147483647),是一个十位数,正好满足了题目10的9次的要求,但v[left] * p就有可能会超出,所以需要强转为(long long),否则会扣去两分
            maxCount = max(maxCount, right - left + 1);
            right++;
        }
    }
    cout << maxCount << endl;
    return 0;
}

本题在第一次写时入了坑,遍历部分是这样写的:

for(int i=1;i<N;i++){
        if(v[0]*p>=v[i]){
            continue;
        }else{
            I=i-1;
            break;
        }
    }

当时的想法是最小值就是升序后的第一个,这样直接往后找最大就行,但事实上整个完美区间应该是可以整个往后移动的,比如当p=8时,数组1 2 3 8 9 10 11 12 13 14 15 16,按原代码的逻辑,以1为最小值,得到的结果为4,但若以2为最小值,得到的正确结果为11。需要多加注意。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值