zoukankan      html  css  js  c++  java
  • 前缀和(狼和野牛)

    位于欧洲中部的赫希费尔登狩猎保护区生活着许多动物,雄壮的野牛和凶狠的狼群之间保持着一种平衡,当野牛的数量和狼群一样多时,它们彼此互不侵犯相安无事,但只要狼的数量多于野牛狼群就会攻击牛群,而野牛数量占多数时,它们会驱逐狼群到别的地方。
    
    当地的统计学家把牛群和狼群分布通过0和1表示为一个字符串S,S的字串可以表示一个区域内的牛和狼总数,请你根据这个统计字符串,判断出来这个保护区内能共存最多头野牛和狼的区域,该区域的牛群和狼群总数是多少。

    输入

    一个字符串,只包含01,长度不超过1000000。

    输出

    一行一个整数,最长的0与1的个数相等的子串的长度。

    样例输入 Copy

    1011

    样例输出 Copy

    2

    提示

    1. 样例解释
    对于1011而言,它表示保护区内分布情况为:[牛,狼,牛,牛]
    那么最多只有[狼,牛]这2只动物存在于某个区域内,所以结果为2
    2. 数据范围
    对于10%的数据,字符串长度≤10;
    对于100%的数据,字符串长度≤1000000。
     
    题目大意:就是找一个字符串中的最长字串(字串要满足01相等)
    解析:

    0看成-1,把1看成+1,则一个子串可以选当且仅当这个串里(区间)的数字之和为0。区间和可以表

    示成两个前缀和的差,而两个前缀和的差为0即两个前缀和相等,记录前缀和为x的最早出现位置

    f[x]

    对于一个前缀和s[i],如果f[s[i]]<i则第f[s[i]]+1个字符到第i个字符组成的串就是一个合法解,且比它短

    的解不会计入答案,用这个长度更新答案即可

    就是找前缀和为0,或者前缀和相等中间夹着的。(……3……3……)两个3中间的,或者是(……0……)就是0前面的。

    AC代码1:(用mp标记前缀和)

    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    using namespace std;
    inline int read() {int x=0,f=1;char c=getchar();while(c!='-'&&(c<'0'||c>'9'))c=getchar();if(c=='-')f=-1,c=getchar();while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return f*x;}
    typedef long long ll;
    const int maxn = 1e7+100;
    char a[maxn];
    int sum[maxn];
    unordered_map<int,int>mp;
    int main()
    {
        gets(a+1);
        int t=strlen(a+1);
        for(int i=1;i<=t;i++){
            if(a[i]=='0'){
                sum[i]=sum[i-1]-1;
            }
            if(a[i]=='1'){
                sum[i]=sum[i-1]+1;
            } 
        }
        int ans=0;
        for(int i=1;i<=t;i++){
            if(sum[i]!=0&&!mp.count(sum[i])){
                mp[sum[i]]=i;//因为是最长所以找第一次出现的sum[i]
            }
            else
            ans=max(ans,i-mp[sum[i]]);
        }
        printf("%d",ans); 
        return 0;
    }

    AC代码2:数组标记:

    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    using namespace std;
    inline int read() {int x=0,f=1;char c=getchar();while(c!='-'&&(c<'0'||c>'9'))c=getchar();if(c=='-')f=-1,c=getchar();while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return f*x;}
    typedef long long ll;
    const int maxn = 1e7+10;
    char a[maxn];
    int vis[maxn];
    int main()
    {
        scanf("%s",a+1);
        int t=strlen(a+1);
        int sum=0;
        int ans=0;
        sum=t; 
        for(int i=1;i<=t;i++){
            if(a[i]=='0'){
                sum--;
            }
            if(a[i]=='1'){
                sum++;
            }   
            if(sum!=t&&vis[sum]==0){
                vis[sum]=i;
            }
            else{
                ans=max(i-vis[sum],ans);
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    银行数仓主题划份
    Halcon 图像的算术运算(crop_part,invert_image,scale_image)
    Halcon 图像截取 crop_part
    Halcon 算子 threshold
    Halcon 图片读取以及图像转换
    Lens shading correction 的四种方法
    Micro-Manage/ImageJ软件使用技巧快问快答
    Micro-Manager基本操作指南(下)
    Micro-Manager基本操作指南(上)
    MATLAB 配置 Micro-Manager
  • 原文地址:https://www.cnblogs.com/lipu123/p/12169548.html
Copyright © 2011-2022 走看看