zoukankan      html  css  js  c++  java
  • 【bzoj4236】JOIOJI STL-map

    题目描述

    JOIOJI桑是JOI君的叔叔。“JOIOJI”这个名字是由“J、O、I”三个字母各两个构成的。
    最近,JOIOJI桑有了一个孩子。JOIOJI桑想让自己孩子的名字和自己一样由“J、O、I”三个字母构成,并且想让“J、O、I”三个字母的出现次数恰好相同。
    JOIOJI桑家有一份祖传的卷轴,上面写着一首长诗,长度为N,由“J、O、I”三个字母组成。JOIOJIさん想用诗中最长的满足要求的连续子串作为孩子的名字。
    现在JOIOJI桑将这首长诗交给了你,请你求出诗中最长的、包含同样数目的“J、O、I”三个字母的连续子串。

    输入

    第一行一个正整数N,代表这首长诗的长度
    接下来一行一个长度为N的字符串S,表示这首长诗,保证每个字符都是“J、O、I”三个字母中的一个

    输出

    输出一行一个正整数,代表最长的包含等数量“J、O、I”三个字母的最长连续子串的长度。如果不存在这样的子串,输出0

    样例输入

    10
    JOIIJOJOOI

    样例输出

    6


    题解

    STL-map

    设a[i]为1~i中'J'的个数,b[i]为1~i中'O'的个数,c[i]为1~i中'I'的个数。

    那么如果[i+1,j]区间可被选择,一定有a[j]-a[i]==b[j]-b[i]==c[j]-c[i],

    即a[j]-b[j]==a[i]-b[i],a[j]-c[j]==a[i]-c[i]。

    根据这个我们可以把a[i]-b[i]和a[i]-c[i]存起来,再从左向右找,如果找到就用j-i更新答案,没找到则扔到map里。

    理论时间复杂度O(nlogn),实际会更快一些。

    考场上懵逼了,写了CDQ分治,效率稍微低了一些,反正就当练手了。

    #include <cstdio>
    #include <map>
    #include <utility>
    using namespace std;
    map<pair<int , int> , int> v;
    char str[200010];
    int main()
    {
    	int n , i , ans = 0 , a = 0 , b = 0;
    	scanf("%d%s" , &n , str + 1);
    	v[make_pair(0 , 0)] = 0;
    	for(i = 1 ; i <= n ; i ++ )
    	{
    		if(str[i] == 'J') a ++ , b ++ ;
    		if(str[i] == 'O') a -- ;
    		if(str[i] == 'I') b -- ;
    		if(v.find(make_pair(a , b)) == v.end()) v[make_pair(a , b)] = i;
    		else ans = max(ans , i - v[make_pair(a , b)]);
    	}
    	printf("%d
    " , ans);
    	return 0;
    }
  • 相关阅读:
    VS2010下配置CxImage
    Visual Studio 2010 开发配置
    主机屋使用感受
    Web开发者必备的20款超赞jQuery插件
    自动页面居中
    jQuery+CSS打造的网页背景颜色切换效果
    小按钮,大学问
    【网站开发必备】——12款响应式 Lightbox(灯箱)效果插件
    修正 IE 的双倍页边距 bug
    a>b?a:b
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/6616996.html
Copyright © 2011-2022 走看看