码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-12-24 12:46:34      阅读:110      评论:0      收藏:0      [点我收藏+]

标签:microsoft   wan   位置   ret   pac   print   字符串   als   ack   

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

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

    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 题解(环展开成链,枚举)

标签:microsoft   wan   位置   ret   pac   print   字符串   als   ack   

原文地址:http://www.cnblogs.com/wannafly1995/p/8097492.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!