USACO Broken Necklace 题解(环展开成链,枚举)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了USACO Broken Necklace 题解(环展开成链,枚举)相关的知识,希望对你有一定的参考价值。

题目大意:有一个项链,由红、蓝、白三种颜色的珠子组成,然后现在选择项链中的某一处断开,然后沿断开处的两个珠子分别查找,直至找到一个颜色不同的珠子,并统计个数(其中颜色以第一个非白色的为准,白色的珠子可以视为红色,也可以视为蓝色),要求找到的珠子个数的最大值。

分析:首先读取项链字符串,考虑到这是一个环,可以在字符串尾部再添加一个同样的项链,这样当向后寻找的时候如果需要超过头结点时候可以直接通过查找第二个项链即可,之所以向后寻找时候不必担心会多查找,是因为只要项链中存在一个颜色不同的珠子必然会停止,但是这样需要我们对两种特殊情况进行判断才可以:

    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 题解(环展开成链,枚举)的主要内容,如果未能解决你的问题,请参考以下文章

Usaco 1.1.4 Broken Necklace

USACO section1.1 Broken Necklace

Broken Necklace 坏掉的项链 USACO 模拟(易错)

P1203 [USACO1.1]坏掉的项链Broken Necklace

P1203 [USACO1.1]坏掉的项链Broken Necklace

洛谷 P1203 [USACO1.1]坏掉的项链Broken Necklace