洛谷 P1203 [USACO1.1]坏掉的项链Broken Necklace
题目描述
你有一条由N个红色的,白色的,或蓝色的珠子组成的项链(3<=N<=350),珠子是随意安排的。 这里是 n=29 的二个例子:
第一和第二个珠子在图片中已经被作记号。
图片 A 中的项链可以用下面的字符串表示:
brbrrrbbbrrrrrbrrbbrbbbbrrrrb
假如你要在一些点打破项链,展开成一条直线,然后从一端开始收集同颜色的珠子直到你遇到一个不同的颜色珠子,在另一端做同样的事(颜色可能与在这之前收集的不同)。 确定应该在哪里打破项链来收集到最大数目的珠子。
例如,在图片 A 中的项链中,在珠子 9 和珠子 10 或珠子 24 和珠子 25 之间打断项链可以收集到8个珠子。
白色珠子什么意思?
在一些项链中还包括白色的珠子(如图片B) 所示。
当收集珠子的时候,一个被遇到的白色珠子可以被当做红色也可以被当做蓝色。
表现含有白珠项链的字符串将会包括三个符号 r , b 和 w 。
写一个程序来确定从一条被给出的项链可以收集到的珠子最大数目。
输入输出格式
输入格式:
第 1 行: N, 珠子的数目
第 2 行: 一串长度为N的字符串, 每个字符是 r , b 或 w。
输出格式:
输出一行一个整数,表示从给出的项链中可以收集到的珠子的最大数量。
输入输出样例
说明
题目翻译来自NOCOW。
USACO Training Section 1.1
解题思路:
先将这个项链(字符串)复制三遍,在中间一段枚举断点,求出所有答案,找出最优答案即可.
AC代码:
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 string a; 5 int ans,n; 6 int fff(int x) {//求将当前元素当作断点的答案 7 int s = 0; 8 char a1 = a[x],b2 = a[x+1]; 9 for(int i = x;; i--) { 10 if(a[i] == a1) s++; 11 else if(a[i] == 'w') s++; 12 else break; 13 } 14 for(int i = x + 1;; i++) { 15 if(a[i] == b2) s++; 16 else if(a[i] == 'w') s++; 17 else break; 18 } 19 return s; 20 } 21 int main() { 22 ans = -1; 23 cin >> n >> a; 24 a = a + a + a;//将项链复制三遍 25 for(int i = n;i < 2 * n; i++) { 26 if(a[i] == a[i+1])//如果当前元素跟他后面的元素一样,说明最优答案的断点一定不在当前元素 27 continue; 28 if(a[i] == 'w') {//如果是白色的珠子,那么当前元素可以是红色也可以是蓝色 29 a[i] = 'r';//如果当做红色 30 ans = max(ans,fff(i)); 31 a[i] = 'b';//如果当做蓝色 32 ans = max(ans,fff(i)); 33 a[i] = 'w'; 34 } 35 ans = max(ans,fff(i)); 36 } 37 ans = min(ans,n);//防止ans超出项链长度 38 if(ans == -1) ans = n;//说明整个项链的颜色一样 39 printf("%d",ans); 40 return 0; 41 }