zoukankan      html  css  js  c++  java
  • 有点意思的双指针

      day1 当然还学习了双指针,当然效率很高。

    这道题很有意思了 数字都是正数。

    秒想到了二分 。nlogn 

    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<iomanip>
    #include<cstring>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<cctype>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<queue>
    #include<stack>
    #include<deque>
    #include<map>
    #include<vector>
    #include<ctime>
    #define INF 2147483646
    using namespace std;
    char buf[1<<15],*fs,*ft;
    inline char getc()
    {
        return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
    }
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    inline void put(int x)
    {
        x<0?putchar('-'),x=-x:0;
        int num=0;char ch[50];
        while(x)ch[++num]=x%10+'0',x/=10;
        num==0?putchar('0'):0;
        while(num)putchar(ch[num--]);
        putchar('
    ');return;
    }
    const int MAXN=100002;
    int T,n,s;
    int a[MAXN];
    int check(int x)
    {
        int maxx=0;
        for(int i=x;i<=n;i++)maxx=max(maxx,a[i]-a[i-x]);
        if(maxx>=s)return 1;
        return 0;
    }
    int main()
    {
        //freopen("1.in","r",stdin);
        T=read();
        while(T--)
        {
            n=read();s=read();
            for(int i=1;i<=n;i++)
            {    
                a[i]=read();
                a[i]+=a[i-1];
            }
            if(a[n]<s){put(0);continue;}
            int l=1,r=n;
            while(l+1<r)
            {
                int mid=(l+r)>>1;
                if(check(mid))r=mid;
                else l=mid;
            }
            if(check(l)==1)put(l);
            else put(r);
        }
        return 0;
    }
    View Code

    但是双指针则可以优化到 O(n);原理是贪心。但是证明 不太会。

    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<iomanip>
    #include<cstring>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<cctype>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<queue>
    #include<stack>
    #include<deque>
    #include<map>
    #include<vector>
    #include<ctime>
    #define INF 2147483646
    using namespace std;
    char buf[1<<15],*fs,*ft;
    inline char getc()
    {
        return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
    }
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    inline void put(int x)
    {
        x<0?putchar('-'),x=-x:0;
        int num=0;char ch[50];
        while(x)ch[++num]=x%10+'0',x/=10;
        num==0?putchar('0'):0;
        while(num)putchar(ch[num--]);
        putchar('
    ');return;
    }
    const int MAXN=100002;
    int T,n,s;
    int a[MAXN];
    int maxx=0,ans;
    int main()
    {
        freopen("1.in","r",stdin);
        T=read();
        while(T--)
        {
            n=read();s=read();maxx=0;ans=INF;
            for(int i=1;i<=n;i++)
            {    
                a[i]=read();
                maxx+=a[i];
            }
            if(s==0){put(1);continue;}
            if(maxx<s){put(0);continue;}
            int tmp=0;
            for(int i=0,j=1;j<=n;j++)
            {
                tmp+=a[j];
                while(tmp>=s)ans=min(ans,j-i+1),tmp-=a[i++];
            }
            put(ans);
        }
        return 0;
    }
    View Code

    但是如果元素的值小于0的话 只能前缀和+二分+单调队列了。。。

    这很显然是排序后双指针扫描。

    但是当前和后面发生碰撞时情况的有两种,设前面指针为i 后面指针为j  且i j相邻

    分两种情况:a[i]+a[j]<=s a[i]+a[j]>s;

    然后 针对 第一种情况 i+1==j 针对第二种情况 i==j;

    对此有三个不同细节的 代码都可解决如下:

    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<iomanip>
    #include<cstring>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<cctype>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<queue>
    #include<stack>
    #include<deque>
    #include<map>
    #include<vector>
    #include<ctime>
    #define INF 2147483646
    using namespace std;
    char buf[1<<15],*fs,*ft;
    inline char getc()
    {
        return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
    }
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    inline void put(int x)
    {
        x<0?putchar('-'),x=-x:0;
        int num=0;char ch[50];
        while(x)ch[++num]=x%10+'0',x/=10;
        num==0?putchar('0'):0;
        while(num)putchar(ch[num--]);
        putchar('
    ');return;
    }
    const int MAXN=20002;
    int n,s;
    int a[MAXN];
    int ans,i,j;
    int cmp(int x,int y){return x>y;}
    int main()
    {
        freopen("1.in","r",stdin);
        n=read();s=read();
        for(int k=1;k<=n;k++)a[k]=read();
        sort(a+1,a+1+n,cmp);
        for(i=1,j=n;i<=j;i++)
        {
            while(i<j&&(a[i]+a[j]<=s))j--;
            //找到了一个与a[i] 不匹配的a[j] j+1;
            //n~(j+1) n-(j+1)+1-> n-j;
            //当 i==j时GG 此时匹配成功的还是 j+1
            //此时 再次累加是正确的
            ans+=(n-j);
        }
        j++;
        //cout<<i<<' '<<j<<endl;
        for(int k=j;k<=n;k++)ans+=(n-k);
        put(ans);
        return 0;
    }
    View Code
    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<iomanip>
    #include<cstring>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<cctype>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<queue>
    #include<stack>
    #include<deque>
    #include<map>
    #include<vector>
    #include<ctime>
    #define INF 2147483646
    using namespace std;
    char buf[1<<15],*fs,*ft;
    inline char getc()
    {
        return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
    }
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    inline void put(int x)
    {
        x<0?putchar('-'),x=-x:0;
        int num=0;char ch[50];
        while(x)ch[++num]=x%10+'0',x/=10;
        num==0?putchar('0'):0;
        while(num)putchar(ch[num--]);
        putchar('
    ');return;
    }
    const int MAXN=20002;
    int n,s;
    int a[MAXN];
    int ans,i,j;
    int cmp(int x,int y){return x>y;}
    int main()
    {
        freopen("1.in","r",stdin);
        n=read();s=read();
        for(int k=1;k<=n;k++)a[k]=read();
        sort(a+1,a+1+n,cmp);
        for(i=1,j=n;i<=j;i++)
        {
            while(i<j&&(a[i]+a[j]<=s))j--;
            //找到了一个与a[i] 不匹配的a[j] j+1;
            //n~(j+1) n-(j+1)+1-> n-j;
            //当 i==j时GG 此时匹配成功的还是 j+1
            //此时 再次累加是正确的
            ans+=(n-j);
        }
        //cout<<i<<' '<<j<<endl;
        for(int k=i;k<=n;k++)ans+=(n-k);
        put(ans);
        return 0;
    }
    View Code
    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<iomanip>
    #include<cstring>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<cctype>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<queue>
    #include<stack>
    #include<deque>
    #include<map>
    #include<vector>
    #include<ctime>
    #define INF 2147483646
    using namespace std;
    char buf[1<<15],*fs,*ft;
    inline char getc()
    {
        return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
    }
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    inline void put(int x)
    {
        x<0?putchar('-'),x=-x:0;
        int num=0;char ch[50];
        while(x)ch[++num]=x%10+'0',x/=10;
        num==0?putchar('0'):0;
        while(num)putchar(ch[num--]);
        putchar('
    ');return;
    }
    const int MAXN=20002;
    int n,s;
    int a[MAXN];
    int ans,i,j;
    int cmp(int x,int y){return x>y;}
    int main()
    {
        //freopen("1.in","r",stdin);
        n=read();s=read();
        for(int k=1;k<=n;k++)a[k]=read();
        sort(a+1,a+1+n,cmp);
        for(i=1,j=n;i<j;i++)
        {
            while(i<j&&(a[i]+a[j]<=s))j--;
            //找到了一个与a[i] 不匹配的a[j] j+1;
            //n~(j+1) n-(j+1)+1-> n-j;
            //当 i==j时GG 此时匹配成功的还是 j+1
            //此时 再次累加是正确的
            ans+=(n-j);
        }
        //cout<<i<<' '<<j<<endl;
        for(int k=i;k<=n;k++)ans+=(n-k);
        put(ans);
        return 0;
    }
    View Code

  • 相关阅读:
    关于lucene断点续索引和增量索引的问题
    发布一个关于统计时间段的MDX语句
    【蛙蛙推荐】想设计一个关于软件开发的元搜索引擎,希望大家支持
    python中and和or的用法
    Hadoop实战中高级部分 之 Hadoop MapReduce高级编程
    (转)对实时分析与离线分析的思考(二)
    数据分析站点导航
    MapReduce:详解Shuffle过程
    分析能力的8个等级(My Level)
    (转)Tire Tree
  • 原文地址:https://www.cnblogs.com/chdy/p/10376370.html
Copyright © 2011-2022 走看看