hdu 5583 Kingdom of Black and White 2015ACM/ICPC亚洲区上海站-重现赛

先缩点,将颜色相同的连续line作为一个点。如果连通块只有一个frog,改变颜色后则会与相邻的两个连通块合为一体,改变量是(a+1+b)^2-(a^2+1+b^2)。如果连通块有多个frog,改变中间的颜色不会更优,因为是从(a+1+b)^2变为a^2+1+b^2只会更小。所以应该改变最左边或最右边frog的颜色,from a^2+b^2 to (a+1)^2+(b-1)^2 or (a-1)^2+(b+1)^2。

#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<string>
#include<cmath>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<cstring>
#include<vector>
#include<queue>
#include<map>

using namespace std;
//hdu 5583
const int maxn=1e5+10;
const int INF=0x3f3f3f3f;
int T;
long long N;
long long ans;
char seq[maxn];
long long presum;
class frog
{
public:
    long long num;
    int color;
public:
    frog()
    {
        num=0;
        color=0;
    }
    frog(int n,int c)
    {
        num=n;
        color=c;
    }
};
frog line[maxn];
int main()
{
    freopen("input.txt","r",stdin);
    scanf("%d",&T);
    for(int ca=1;ca<=T;ca++)
    {
        ans=0;
        memset(seq,0,sizeof(seq));
        memset(line,0,sizeof(line));
        scanf("%s",&seq);
        presum=0;
        N=strlen(seq);
        seq[N]='2';
        //cout<<seq<<endl;
        if(N==1)
        {
            printf("Case #%d: 1\n",ca);
            continue;
        }
        long long cnt=1;
        int idx=0;
        for(int i=0;i<N;i++)
        {
            if(seq[i]==seq[i+1])
            {
                cnt++;
//                if(i==N-2)
//                {
//                    line[idx]=frog(cnt,seq[i]-'0');
//                }
            }
            else
            {
                line[idx]=frog(cnt,seq[i]-'0');
                cnt=1;
                idx++;
//                if(i==N-2)
//                {
//                    line[idx]=frog(cnt,seq[i]-'0');
//                }
            }
        }
//        line[idx].num=1;
//        line[idx].color=seq[0]-'0';
//        for(int i=1;i<N;i++)
//        {
//
//            if(seq[i]==seq[i-1])
//            {
//                line[idx].num++;
//            }
//            else
//            {
//                idx++;
//                line[idx].num++;
//                line[idx].color=seq[i]-'0';
//            }
//        }
//        idx++;
        //cout<<"idx "<<idx<<endl;
        if(idx==1)
        {
            printf("Case #%d: %I64d\n",ca,N*N);//line[0].num*line[0].num);
            continue;
        }

        //for(int i=0;i<idx;i++) cout<<line[i].num<<" "<<line[i].color<<endl;
        //int maxlen=0;
        for(int i=0;i<idx;i++)
        {
            //cout<<"num^2 "<<(line[i].num^2)<<endl;
            presum+=line[i].num*line[i].num;
            //maxlen=max(maxlen,line[i].num);
//            if(maxlen<line[i].num)
//            {
//                maxlen=line[i].num;
//                maxidx=i;
//            }
            if(line[i].num==1)
            {
                if(i==0)
                {
                    ans=max(ans,(2*line[i+1].num));
                }
                else if(i==idx-1)
                {
                    ans=max(ans,(2*line[i-1].num));
                }
                else
                {
//                    if(line[i-1].color==line[i+1].color)
//                    {
                        ans=max(ans,2*(line[i-1].num+line[i+1].num+line[i-1].num*line[i+1].num));
                    //}
//                    else
//                    {
//                        ans=max(ans,(1+max(line[i-1].num,line[i+1].num)^2); must be 3 different colors
//                    }

                }

            }
        }
//        for(int i=1;i<idx;i++)
//        {
//            if(line[i].num==1)
//            {
//                ans=max(ans,2*(line[i-1].num+line[i+1].num+line[i-1].num*line[i+1].num));
//            }
//        }
//        for(int i=0;i<idx;i++)
//        {
//            if(line[i].num==maxlen)
//            {
//                if(i==0) ans=max(ans,2*(line[i].num-line[i+1].num)+2);
//                else if(i==idx-1) ans=max(ans,2*(line[i].num-line[i-1].num)+2);
//                else
//                {
//                    int b=min(line[i-1].num,line[i+1].num);
//                    ans=max(ans,2*(line[i].num-b)+2);
//                }
//            }
//        }
        for(int i=0;i<idx-1;i++)//current+1, right-1
        {
//            if(line[i].num>=line[i+1].num)
//            {
                ans=max(ans,2*(line[i].num-line[i+1].num)+2);
//            }
//            else
//            {
//                ans=max(ans,2*(line[i+1].num-line[i].num)+2);
//            }
        }
        for(int i=1;i<idx;i++)//current+1, left-1
        {
            ans=max(ans,2*(line[i].num-line[i-1].num)+2);
        }
        //cout<<presum<<endl;
        printf("Case #%d: %I64d\n",ca,presum+ans);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值