<题目链接>
题目大意:
给你一段只由 'B'和'R'组成的字符串,问你在连续的区间内,"B"和"R"的差值最大是多少,输出该区间;如果对于差值相等的区间,优先输出左端点小的,左端点相同,优先输出右端点小的。
解题分析:
很明显要分两种情况讨论,一种是该区间内B比R多,第二种是该区间内R比B多。仔细思考后发现,可以将此题转化为最大连续和问题,对于B多的情况,用dp1来维护,将B看成1,R看成-1,对于R多的情况则用dp2来维护,将R看成1,B看成-1,然后就是用dp求解最大连续和即可,同时记录一下最大连续和所在的区间。
#include <cstdio> #include <cstring> const int M =1e5+7; #define INF 0x3f3f3f3f int main(){ char str[M]; scanf("%s",str+1); int len=strlen(str+1); int dpB[M],dpR[M]; for(int i=1;i<=len;i++){ if(str[i]=='B')dpB[i]=1; else dpB[i]=-1; if(str[i]=='R')dpR[i]=1; else dpR[i]=-1; } int s1,e1,s2,e2; //分别记录两种情况的最优区间 dpB[0]=-1,dpR[0]=-1; int start1,start2,end1,end2; int mx1=-INF; for(int i=1;i<=len;i++){ //先讨论B比R多的情况,求出B比R多的最大连续和 if(dpB[i-1]>=0)dpB[i]=dpB[i-1]+dpB[i]; else s1=i; if(mx1<dpB[i]){ mx1=dpB[i]; start1=s1; end1=i; } } int mx2=-INF; for(int i=1;i<=len;i++){ //讨论R比B多的情况,求出R比B多的最大连续和 if(dpR[i-1]>=0)dpR[i]=dpR[i-1]+dpR[i]; else s2=i; if(mx2<dpR[i]){ mx2=dpR[i]; start2=s2; end2=i; } } //然后就是比较两种情况的最大连续和,并且当最大连续和相同时,按题目要求格式输出 if(mx1>mx2){ printf("%d %d\n",start1,end1); } else if(mx1==mx2){ if(start1<start2) printf("%d %d\n",start1,end1); else if(start1==start2){ printf("%d ",start1); end1<end2?printf("%d\n",end1):printf("%d\n",end2); } else{ printf("%d %d\n",start2,end2); } } else{ printf("%d %d\n",start2,end2); } return 0; }
2018-09-17