PAT A1044

我真傻,真的

题目链接

way1:two points

当输入为1的时候要特判
这个我知道,
但鬼能想到我输出了那个数,,,,

okk,其实可以直接下标从1开始

本来还想过用一次遍历,然后搞一个数组存之前那个maxn,,
判断条件太复杂了,放弃了:-(

#include<iostream>
#include<vector>
#include <queue>
#include <algorithm>
#include<cstdio>
#include <map>
using namespace std;
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    int num[100010];
    for (int i = 0; i < n; ++i) {
        scanf("%d",&num[i]);
    }

    int count=0;
    int j=0;//left
    if(n==1){
        cout<<"1-1"<<endl;
    }
    else {
        int maxn = 0x3f3f3f3f;//这是所有数中,大于等于m中的最小的
        for (int i = 0; i < n; ++i) {
            count += num[i];
            while (i < n && count >= m) {//限制>=m
                maxn = min(maxn, count);
                count -= num[j];
                j++;
            }
        }
        int q = 0;
        count = 0;
        for (int i = 0; i < n; ++i) {
            count += num[i];
            while (i < n && count >= m) {//限制>=m
                if (count == maxn) {
                    cout << q + 1 << "-" << i + 1 << endl;
                }
                count -= num[q];
                q++;
            }
        }
    }


}

way2 前缀和+二分

车祸现场:

舒服了:

不得不说,二分的边界问题太难处理了,有什么问题肯定首想第一个问题

#include<iostream>
#include<vector>
#include <queue>
#include <algorithm>
#include<cstdio>
#include <map>
using namespace std;
//二分+前缀和
int num[100010];
int sum[100020];
int upper_bound(int l ,int r,int x){//返回 (l,r)内第一个大于 x的值
    int right = r;
    int left = l;
    int mid;
    while(left<right){
        mid=(left+right)/2;
        if(sum[mid]>x){//这里是大于,也就是说如果mid刚好等于x的话是会往上移动的
            right=mid;//注意这里不是mid-1
        }
        else{
            left=mid+1;
        }
    }
    return left;

}
int main() {
    int n, m;
    scanf("%d %d", &n, &m);

    int maxn = 0x3f3f3f3f;
    for (int i = 1; i <= n; ++i) {//下标从一开始不需要特判
        scanf("%d", &num[i]);
        sum[i] += sum[i - 1] + num[i];
    }
    for (int i = 1; i <= n; ++i) {
        int j = upper_bound(i, n + 1, sum[i - 1] + m);
        if (sum[j - 1] - sum[i - 1] == m) {//返回的是>,所以你要搞j-1
            maxn = m;
            break;
        } else if (j <= n && sum[j] - sum[i - 1] < maxn) {
            maxn = sum[j] - sum[i - 1];

        }

    }


    for (int i = 1; i <= n; ++i) {
        int j = upper_bound(i, n + 1, sum[i - 1] + maxn);
        if(sum[j-1]-sum[i-1]==maxn){
            cout<<i<<"-"<<j-1<<endl;
        }

    }


}
posted @ 2021-07-25 18:19  安之若醇  阅读(30)  评论(0编辑  收藏  举报
Live2D服务支持