zoukankan      html  css  js  c++  java
  • 给定一个0-1串,请找到一个尽可能长的子串,其中包含的0与1的个数相等。

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1393

    这题解法很奇妙。也是看了别人的思路才想出来.

    首先考虑把0全部变成-1。然后统计一个前缀和,用sum[i]表示.

    那么从起点开始的子串是合法的只要sum[i]的值等于0即可.

    如果子串起点不为0,那么只要两次出现sum[i],这两个数值之间一定是合法的子串.

    例如:

      标号:   1  2  3  4  5  

      数值      0  0  1  1  0  

      sum     -1 -2 -1 0  -1

    i==4的时候sum[i]==0,所以1-4之间是一个合法的子串,长度为4  

    sum[1]==sum[3]==sum[5]== -1,所以 (1,3],(1,5],(3,5]之间都是合法的子串,取最大值也是4.

    我是用了map,其实不用这么麻烦,只要用一个变量就可以代替sum数组,并且另外开一个标记数组可以代替map做映射.

     1 #include <iostream>
     2 #include <string.h>
     3 #include <stdio.h>
     4 #include <map>
     5 using namespace std;
     6 char s[1000010];
     7 int t[1000010],sum[1000010];
     8 int main()
     9 {
    10     //freopen("a.txt","r",stdin);
    11     scanf("%s",s+1);
    12     int l=strlen(s+1);
    13     for(int i=1;i<=l;i++)
    14         if(s[i]=='0') t[i]=-1;
    15         else t[i]=1;
    16     //for(int i=0;i<l;i++) printf("%d",t[i]);
    17     sum[1]=t[1];
    18     map<int,int>m;
    19     m[sum[1]]=1;
    20     int maxn=0;
    21     for(int i=2;i<=l;i++)
    22     {
    23         sum[i]=sum[i-1]+t[i];
    24         //printf("%d
    ",sum[i]);
    25         if(m[sum[i]]!=0) maxn=max(maxn,i-m[sum[i]]);
    26         else m[sum[i]]=i;
    27         if(sum[i]==0) maxn=max(maxn,i);
    28     }
    29     printf("%d
    ",maxn);
    30     return 0;
    31 }
  • 相关阅读:
    asp.net保存远程图片
    JS中的转义字符
    SQL_统计某列的和
    SQL Server 出错自动回滚
    SQL中的循环语句_类似FOR循环
    转 C# 控制IE
    抓取html 写正则
    正则截取内容
    用于测试的字符串
    C#关闭IE相应的窗口 .
  • 原文地址:https://www.cnblogs.com/nowandforever/p/4620372.html
Copyright © 2011-2022 走看看