Educational Codeforces Round 55 (Rated for Div. 2) B. Vova and Trophies
https://www.cnblogs.com/violet-acmer/p/10035971.html
题意:
Vova有n个奖杯,这n个奖杯全部是金奖或银奖,Vova将所有奖杯排成一排,你最多可以交换其中两个奖杯,求最大的连续的金奖杯个数。
题解:
思路:
求出连续的金奖杯位置,找出每两个相邻的连续的金奖杯所能够形成的最大的连续的金奖杯的个数,输出最大值。
相关变量解释:
1 int n; 2 char trophy[maxn]; 3 struct Node 4 { 5 int l,r;//连续金奖杯包含的区间[l,r) 6 Node(int _a=0,int _b=0):l(_a),r(_b){} 7 }gold[maxn];//记录连续金奖杯的位置信息
步骤:
(1):遍历一遍数组,记录出连续金奖杯的左右区间;
(2):每两个连续区间求最大连续的金奖杯个数
具体看代码:
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 const int maxn=1e5+10; 5 6 int n; 7 char trophy[maxn]; 8 struct Node 9 { 10 int l,r;//连续金牌包含的区间[l,r) 11 Node(int _a=0,int _b=0):l(_a),r(_b){} 12 }gold[maxn];//记录连续金牌的位置信息 13 14 int Solve() 15 { 16 int index=0; 17 int cnt=0; 18 gold[1]=Node(0,0);//初始化gold[1],防止没有'G'的情况 19 while(index < n) 20 { 21 while(index < n && trophy[index] == 'S') 22 index++; 23 int l=index; 24 while(index < n && trophy[index] == 'G') 25 index++; 26 int r=index; 27 if(l != r) 28 gold[++cnt]=Node(l,r); 29 } 30 int res=gold[1].r-gold[1].l;//res初始化为gold[1]的金奖杯长度,防止只有一个连续的金奖杯 31 for(int i=2;i <= cnt;++i)//从第二个开始,每次查找i和i-1可以形成的最大的连续的金奖杯个数 32 { 33 int preG=gold[i-1].r-gold[i-1].l; 34 int backG=gold[i].r-gold[i].l; 35 36 if(gold[i].l-gold[i-1].r == 1)//如果两个连续的金奖杯间只有一个银奖杯 37 res=max(res,preG+backG+(cnt > 2 ? 1:0)); 38 else 39 res=max(res,max(preG,backG)+1); 40 } 41 return res; 42 } 43 44 int main() 45 { 46 scanf("%d",&n); 47 scanf("%s",trophy); 48 printf("%d\n",Solve()); 49 }
在trophy的最前和最后各补一个'S',每次查找相邻的三个'S',判断是否可以通过将第二个'S'换成‘G'使连续的金奖杯个数最大。