zoukankan      html  css  js  c++  java
  • bzoj4236JOIOJI

    bzoj4236JOIOJI

    题意:

    给一个只由JOI三个字母组成的串,求最长的一个子串使其中JOI三个字母出现次数相等。串长度≤200000

    题解:

    有点像bzoj4384,因此推算的过程是差不多的,但还是有不同因为本题要求的是出现次数相等,而那题要求的是不等:

    cnt[1][i]-cnt[1][j]==cnt[2][i]-cnt[2][j],cnt[2][i]-cnt[2][j]==cnt[3][i]-cnt[3][j],cnt[1][i]-cnt[1][j]==cnt[3][i]-cnt[3][j]

    化简得到cnt[1][i]-cnt[2][i]==cnt[1][j]-cnt[2][j],cnt[2][i]-cnt[3][i]==cnt[2][j]-cnt[3][j],cnt[1][i]-cnt[3][i]==cnt[1][j]-cnt[3][j](本式实际上是冗余的因为可由前两式相加得到)

    故可以用一个map维护二元组<cnt[1][i]-cnt[2][i],cnt[2][i]-cnt[3][i]>的最早出现次数i,每次在map中查找键值中有没有和当前元素的<cnt[1]-cnt[2],cnt[2]-cnt[3]>相等的元素,有的话和答案比较,否则插入map。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <map>
     5 #define maxn 200100
     6 #define inc(i,j,k) for(int i=j;i<=k;i++)
     7 using namespace std;
     8 
     9 int a,b,c,d,e,n,ans; char s[maxn];
    10 map<pair<int,int>,int>m;
    11 int main(){
    12     scanf("%d%s",&n,s+1); m[make_pair(0,0)]=0;
    13     inc(i,1,n){
    14         if(s[i]=='J')a++; if(s[i]=='O')b++; if(s[i]=='I')c++; d=a-b; e=b-c;
    15         if(m.find(make_pair(d,e))==m.end())m[make_pair(d,e)]=i;
    16         else ans=max(ans,i-m[make_pair(d,e)]);
    17     }
    18     printf("%d",ans); return 0;
    19 }

    20160814

  • 相关阅读:
    python字符串格式化笔记
    看球时的随笔——“如何掌握新的知识”
    str()和repre()的区别
    关于抛出异常和捕获异常
    python关键字详解
    博客的第一天
    PEP8 Python 编码规范
    SQL Server 自动循环归档分区数据脚本
    反射应用--取得类的结构
    回调函数callback使用例子
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5778065.html
Copyright © 2011-2022 走看看