编程题2_字节跳动2018校招测试开发方向(第一批)_牛客网
区间内的所有数字都在[0, 100]的范围内,但是个数却远超100,所以可以采用计数排序的思路。
emmm。。。写完才发现自己理解错题目了,题目说的区间应该是输入序列的连续区间,所以就不是上面的计数排序思路了,应该是用类似滑动窗口的思路。
但是这儿的滑动窗口是可以优化的,不用一次增加一个数这样,需要适当进行“剪枝”。比如窗口右边的数字大于等于窗口最小值的时候,把右边数字加入窗口肯定会使得目标和更大(也就是尽可能的延伸区间)。具体优化在注释里:
#include<iostream>
using namespace std;
int a[500001] = {0};
int main(){
int n;
cin >> n;
int res = 0;
for(int i = 0; i < n; ++i){
cin >> a[i];
res = max(res, a[i]*a[i]);//输入的时候就可以计算窗口内只有一个元素的情况
}
for(int i = 0; i < n; ++i){//遍历以元素a[i]开始的区间
if(a[i] == 0) continue;
if(i != 0 && a[i] <= a[i-1]) continue;//因为任何a[i]开始的区间,在前面加上a[i-1]都会使得目标和更大
int l = i, r = i+1;//左右边界
int sum = a[l], min_val = a[l];
while(r < n){
if(a[r] == 0) break;//没必要再继续下去了
min_val = min(min_val, a[r]);//更新区间内最小值
sum += a[r++];//从至少两个元素的时候开始计算
while(r < n && a[r] >= min_val)//此时一直往窗口里添加元素,会使目标和更大
sum += a[r++];
res = max(res, sum*min_val);
}
}
cout << res << endl;
return 0;
}
这样就可以直接ac了。
看了评论之后还有其他思路,可以先对最小值进行遍历,因为可能的最小值就是1~100,依次遍历每个可能的最小值也是可行的。