又爆零!!!
1001 Price List
求出所有数的和sum,如果q>sum那么肯定记多了。
时间复杂度O(n)。
1001: 大水题,忘记LL了,最后又Wa了。
1002 NanoApe Loves Sequence
求出前i个数里相邻差值的最大值fi,i到n里相邻差值的最大值gi,那么ans=∑i=1nmax(∣Ai−1−Ai+1∣,fi−1,gi+1)。
时间复杂度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 Ⅱ
将不小于m的数看作1,剩下的数看作0,那么只要区间内1的个数不小于k则可行,枚举左端点,右端点可以通过two-pointer求出。
时间复杂度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;
}