BestCoder Round #86

又爆零!!!

1001 Price List

求出所有数的和sumsum,如果q > sumq>sum那么肯定记多了。

时间复杂度O(n)O(n)


1001:   大水题,忘记LL了,最后又Wa了。

1002 NanoApe Loves Sequence

求出前ii个数里相邻差值的最大值f_ifiiinn里相邻差值的最大值g_igi,那么ans=\sum_{i=1}^n \max(|A_{i-1}-A_{i+1}|,f_{i-1},g_{i+1})ans=i=1nmax(Ai1Ai+1,fi1,gi+1)

时间复杂度O(n)O(n)


1002:给你n个数的数列,任意删除一个数再求相邻两数差的绝对值的最大值,求最大值的期望,其实就是求出每删除一个数的最大绝对值之和。


一开始又想到方法,但是后来越想越复杂,每当自己写的东西很复杂的时候就知道不对了。。。。

对于删除一个位置X的数,最大绝对值=max{(0,X-1)的最大值,abs(A[X+1]-A[X-1]),(x+1,n)的最大值}

从前遍历求出f[i](0~i)之间的最大值,从后遍历求出g[i](i~n)的最大值

#include<stdio.h>
#include<string.h>
#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#include <cstdlib>
using namespace std;
#define N 100010
typedef long long ll;    
int n,m,t;
ll a[N],x;
int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        ll ans=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&x);
            ans+=x;
        }
        for(int i=0;i<m;i++)
        {
            scanf("%I64d",&x);
            if(ans<x)
            printf("1");
            else 
            printf("0");
        }
        printf("\n");
    }
    return 0;
}

1003 NanoApe Loves Sequence Ⅱ

将不小于mm的数看作11,剩下的数看作00,那么只要区间内11的个数不小于kk则可行,枚举左端点,右端点可以通过two-pointer求出。

时间复杂度O(n)O(n)


1003:给你n个数的数列,一个m个值,求出有多少个区间第k大的数不小于m。

一看到第k大这几个字眼,就觉得要用数据结构了,什么线段树,主席树,,,额,就不想做了,,,看了题解,很短,看到two-pointer不知什么鬼,百度一下,太多东西又看不进去,看别人的题解,其实就是用尺取法。

对于区间【i,j】,若区间内的1的数等于k,则【i,j】,【i,j+1】,[i,j+2]等以后的区间均符合。。。。

所以用尺取法,O(n),注意跳出循环条件r<=n

#include<stdio.h>
#include<string.h>
#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#include <cstdlib>
#include <map>
using namespace std;
#define N 1000100
typedef long long ll;	
int n,m,t,k,b[N];
int a[N];
ll sum;

void print(int *r)
{
	for(int i=1;i<=n;i++)
	cout<<r[i]<<" ";
	cout<<endl;
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt","r",stdin);
#endif
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d%d",&n,&m,&k);
		for(int i=0;i<n;i++)
		{
			scanf("%d",&a[i]); b[i]=(a[i]>=m)?1:0;
		}
		sum=0;
		int l=0,r=1,ans=b[0];
		while(l<r&&r<=n){
			if(ans==k)
			{
				sum+=n-r+1;
				ans-=b[l++];
			}
			else
			{
				ans+=b[r++];
			}
		}
		printf("%I64d\n",sum);
	}
	return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值