USACO 1.1 Broken Necklace

题目链接:http://ace.delos.com/usacoprob2?a=RfmQrEONAFb&S=beads

今天开始重做usaco了。上次是去年这个时候了,一眨眼一年就过去了。做了两个月才到4.3,后来就没做了。
现在重新开始吧。

beads这题,比较巧妙的地方就是把字符串复制一份,从而就避免了边界检查。
用left[0][i]来记录从某一点向左可以收集到的最长r色beads数
用left[1][i]来记录从某一点向左可以收集到的最长b色beads数
right数组类推。

显然,如果i为r色,则向左可以收集到的最长r色为left[0][i-1]+1.可以向左收集到的最长b色为0。
如果i为b色,类推。
如果i为w色,i即可做r,也可做b.所以各自加1.

代码如下:
#include <iostream>
#include 
<fstream>

using namespace std;

ifstream fin(
"beads.in");
ofstream fout(
"beads.out");

#ifdef _DEBUG
#define out cout
#define in cin
#else
#define out fout
#define in fin
#endif

//为简化代码,在数组前后各加1位,这样i+1,i-1不会越界,也无需对边界情况特殊处理。
int l[2][702];
int r[2][702];


void solve()
{
    
int num;
    
in>>num;

    
string s;
    
in>>s;
    s
+=s;

    memset(r,
0,sizeof(l));
    memset(r,
0,sizeof(r));

    
for(int i=s.size();i>=1;--i){
        
if(s[i-1]=='r'){
            r[
0][i] = r[0][i+1]+1;
            r[
1][i] = 0;
        }
else if(s[i-1]=='b'){
            r[
0][i] = 0;
            r[
1][i] = r[1][i+1]+1;
        }
else{
            r[
0][i] = r[0][i+1]+1;
            r[
1][i] = r[1][i+1]+1;
        }
    }

    
for(int i=1;i<=s.size();++i){
        
if(s[i-1]=='r'){
            l[
0][i] = l[0][i-1]+1;
            l[
1][i] = 0;
        }
else if(s[i-1]=='b'){
            l[
0][i] = 0;
            l[
1][i] = l[1][i-1]+1;
        }
else{
            l[
0][i] = l[0][i-1]+1;
            l[
1][i] = l[1][i-1]+1;
        }
    }

    
int res = INT_MIN;

    
for(int i=1;i<=num;++i){
        res 
= max(res, max(r[0][i],r[1][i])+max(l[0][i+num-1],l[1][i+num-1]));
    }

    
// 在出现重叠的情况下,res会大于num.最大只能是num
    res = min(res,num);

    
out<<res<<endl;
}

int main(int argc,char *argv[])
{
    solve();
    
return 0;
}




posted on 2009-06-04 20:54 YZY 阅读(1035) 评论(0)  编辑 收藏 引用 所属分类: AlgorithmUSACO


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2009年6月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

统计

常用链接

留言簿(2)

随笔分类

随笔档案

搜索

积分与排名

最新评论

阅读排行榜