USACO 1.1-beads

题意:

给一个项链(首尾相连),从某个地方断开,然后两头取相同的珠子,问最多能取多少个
有三种珠子:r,w,b。其中w是百变珠子,可以当成w或者r。

类型:

模拟

思路:

首先,断开的地方不会是某个连续串的中间(因为,断开在中间比断开在两头非但不会得到更好的结果,反而可能得到更差的结果)
其次,bw..wb = b..b  rw..wr = r..r
整个程序的思路就是
先压缩字符串(把相同的合并)
然后处理第二个条件
再次压缩,得到最终串
然后枚举每个地方,模拟人去取,看能取多少个
(关键是考虑好各种特殊情况。。。。恶心啊)

代码:

/*
PROG: beads
LANG: C++
*/
/*************************************************************************
    > File Name:    usaco1-1-beads.cpp
    > Author:       Shine
    > Created Time: 2013-05-20 下午 12:39:47
    > QuestionType: 模拟
    > Way: 模拟
    > Submit: 3WA 1A
    > Gain: 小心模拟
    > Experience: 小心模拟
 ************************************************************************/

//b???b => bbbbb
//a???a => aaaaa
//a???b
//wwwbbrwrbrbrrbrbrwrwwrbwrwrrb
//bbbbbrrrbrbrrbrbrrrrrrbwrrrrb
//brbrbrbrbrbwr
//6311121116114
//左右找两个。如果两个之中有w,则加,否则取最近一个
//
//特例:
//bbb
//b
//3
#include <cstdio>
#include <cstring>

int n;
char str[1000];

void Compress(char str[],int nu[]){
    //把多个连续字符压缩成单个字符
    int i;
    int n = strlen(str);
    char compress[1000];
    int num[1000];
    int p = 0;

    //找连续串的最后一个字符
    for (i = 0; i < n && str[i] != -1; i++) { //str[i] == -1说明被删除了,然而删除就是连续的,说明前面都被删除了
        if (str[i] != str[(i+1)%n]) {
            int k;
            compress[p] = str[i];
            num[p] = nu[i];
            for (k = (i-1+n)%n; k != i; k = (k-1+n)%n) {//向前搜索
                if (str[k] == compress[p]) {
                    num[p] += nu[k];
                    str[k] = -1;
                } else {
                    p++;
                    break;
                }
            }
        }
    }
    
    //特殊情况:整个串都连续……
    if (p == 0) {
        compress[p] = str[0];
        num[p] = 0;
        int len = strlen(str);
        int k;
        for (k = 0; k < len; k++) {
            num[p] += nu[k];
        }
        p++;
    }

    compress[p] = 0;

    for (i = 0; compress[i]; i++) {
        str[i] = compress[i];
        nu[i] = num[i];
    }
    str[i] = 0;

    //puts(compress);
    //for (i = 0; i < p; i++) {
    //    printf("%d", num[i]);
    //}puts("");
}

int main() {
    freopen("beads.in", "r",stdin);
    freopen("beads.out", "w", stdout);
    scanf("%d", &n);
    scanf("%s", str);
    int i;
    int ans = 0;
    int num[1000];
    for (i = 0; i < 1000; i++) {
        num[i] = 1;
    }

    Compress(str, num);
    //puts(str);

    int len = strlen(str);
    for (i = 0; i < len; i++) {
        if (str[i] == 'w' && str[(i-1+len)%len] == str[(i+1)%len]) {
            str[i] = str[(i+1)%len];
        }
    }
    //puts(str);

    Compress(str, num);
    
    len = strlen(str);

    for (i = 0; i < len; i++) {
        int tmpans = 0;
        int vis[1000] = {0};
        int k;
        int pickn = 0;

        //printf("i = %d\n", i);
        for (k = i; str[k] == 'w' && k != (i-1+len)%len; k = (k+1)%len);

        char good = str[k];
        //printf("->good = %c\n", good);
        for (k = i; pickn < len; k = (k+1)%len) {
            if (str[k] == good || str[k] == 'w') {
                if (!vis[k]) {
                    vis[k] = 1;
                    pickn++;
                    tmpans += num[k];
                } else break;
            } else break;
        }

        for (k = (i-1+len)%len; str[k] == 'w' && k != i; k = (k-1+len)%len);
        good = str[k];
        //printf("<-good = %c\n", good);
        for (k = (i-1+len)%len; pickn < len; k = (k-1+len)%len) {
            if (str[k] == good ||str[k] == 'w') {
                if (!vis[k]) {
                    vis[k] = 1;
                    pickn++;
                    tmpans += num[k];
                }else break;
            } else break;
        }
        if (ans < tmpans) ans = tmpans;
    }

    printf("%d\n", ans);
    return 0;
}
USACO 1.1-beads

 

posted on 2013-05-20 15:45  ShineCheng  阅读(187)  评论(0编辑  收藏  举报

导航