1. 程式人生 > >USACO Broken Necklace 題解(環展開成鏈,枚舉)

USACO Broken Necklace 題解(環展開成鏈,枚舉)

相同 == name 第一個 span bre 我們 return style

題目大意:有一個項鏈,由紅、藍、白三種顏色的珠子組成,然後現在選擇項鏈中的某一處斷開,然後沿斷開處的兩個珠子分別查找,直至找到一個顏色不同的珠子,並統計個數(其中顏色以第一個非白色的為準,白色的珠子可以視為紅色,也可以視為藍色),要求找到的珠子個數的最大值。

分析:首先讀取項鏈字符串,考慮到這是一個環,可以在字符串尾部再添加一個同樣的項鏈,這樣當向後尋找的時候如果需要超過頭結點時候可以直接通過查找第二個項鏈即可,之所以向後尋找時候不必擔心會多查找,是因為只要項鏈中存在一個顏色不同的珠子必然會停止,但是這樣需要我們對兩種特殊情況進行判斷才可以:

1.顏色全部相同的項鏈;

2.除了白色珠子以外,所有的顏色也都相同,那麽這樣也可以視為項鏈顏色全部相同;

  1 /*
  2 ID:wannafly1995
  3 TASK:beads
  4 LANG:C++
  5 */
  6 #include  <cstdio>
  7 #include  <cstring>
  8 #include  <cstdlib>
  9 #include  <iostream>
 10 #include  <algorithm>
 11 using namespace std;
 12 const int maxn = 750;
 13 int n, cnt[maxn >> 1], Left, Right, sum;
14 char s[maxn], tag1, tag2, forward[maxn >> 1], backward[maxn >> 1]; 15 bool check() { 16 bool tag = true; 17 for(int i = 2; i <= n; i++) { 18 if(s[i] != s[1]) { 19 tag = false; 20 } 21 } 22 sum = 0; 23 for(int i = 1; i <= n; i++) {
24 if(s[i] == b) { 25 sum += 1; 26 } 27 if(s[i] == r) { 28 sum += 5; 29 } 30 if(s[i] == w) { 31 sum += 9; 32 } 33 } 34 //其中sum為10或者14代表除了白色珠子以外的所有珠子顏色相同 35 if(sum == 10 || sum == 14) { 36 tag = true; 37 } 38 return tag; 39 } 40 int main() { 41 freopen("beads.in", "r", stdin); 42 freopen("beads.out", "w", stdout); 43 memset(cnt, 0, sizeof(cnt)); 44 scanf("%d\n", &n); 45 for(int i = 1; i <= n; i++) { 46 scanf("%c", &s[i]); 47 } 48 for(int i = n + 1; i <= (n * 2); i++) { 49 s[i] = s[i - n]; 50 } 51 s[n * 2 + 1] = \0; 52 //判斷特殊情況 53 if(check()) { 54 printf("%d\n", n); 55 return 0; 56 } 57 //下邊這部分用來查找每個位置向前或者向後的第一個非白色珠子 58 for(int i = n + 1; i <= 2 * n; i++) { 59 for(int j = i; j >= i - n + 1; j--) { 60 if(s[j] != w) { 61 forward[i - n] = s[j]; 62 break; 63 } 64 } 65 } 66 for(int i = 1; i <= n; i++) { 67 for(int j = i; j <= i + n - 1; j++) { 68 if(s[j] != w) { 69 backward[i] = s[j]; 70 break; 71 } 72 } 73 } 74 for(int i = 1; i <= n; i++) { 75 Left = i, Right = i + 1; 76 tag1 = forward[i], tag2 = backward[i + 1]; 77 //向前查找 78 while(true) { 79 if(Left == 0) { 80 break; 81 } 82 if(tag1 == s[Left] || s[Left] == w) { 83 cnt[i]++; 84 } else { 85 break; 86 } 87 Left--; 88 } 89 //向後查找 90 while(true) { 91 if(Right > n * 2) { 92 break; 93 } 94 if(tag2 == s[Right] || s[Right] == w) { 95 cnt[i]++; 96 } else { 97 break; 98 } 99 Right++; 100 } 101 } 102 int ans = cnt[1]; 103 for(int i = 2; i <= n; i++) { 104 ans = max(ans, cnt[i]); 105 } 106 printf("%d\n", ans); 107 return 0; 108 }

USACO Broken Necklace 題解(環展開成鏈,枚舉)