字符串-hdu_5583_Kingdom of Black and White

来源:互联网 发布:类似于yolo的软件 编辑:程序博客网 时间:2024/05/17 02:18

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5583

题目描述:

Kingdom of Black and White

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1026    Accepted Submission(s): 323


Problem Description
In the Kingdom of Black and White (KBW), there are two kinds of frogs: black frog and white frog.

Now N frogs are standing in a line, some of them are black, the others are white. The total strength of those frogs are calculated by dividing the line into minimum parts, each part should still be continuous, and can only contain one kind of frog. Then the strength is the sum of the squared length for each part.

However, an old, evil witch comes, and tells the frogs that she will change the color ofat most one frog and thus the strength of those frogs might change.

The frogs wonder the maximum possible strength after the witch finishes her job.
 

Input
First line contains an integer T, which indicates the number of test cases.

Every test case only contains a string with length N, including only 0 (representing
a black frog) and 1 (representing a white frog).

1T50.

for 60% data, 1N1000.

for 100% data, 1N105.

the string only contains 0 and 1.
 

Output
For every test case, you should output "Case #x: y",wherex indicates the case number and counts from 1 and y is the answer.
 

Sample Input
20000110101
 

Sample Output
Case #1: 26Case #2: 10
 

Source
2015ACM/ICPC亚洲区上海站-重现赛(感谢华东理工)  

题意:有一个包含0,1的字符串,将字符串分块,每个块是连续的,并且都是0或者都是1.一个字符串的长度定义为每个块长度的平方,然后求和。
问:最多改变一个字符的情况下,就是1变为0,0变为1,也可以不改变。这个字符串的长度的最大值。

分析:分析可知,如果想要长度大于原来的长度,需要改变的字符的位置是0和1相邻的地方,这样有的块的长度变长了,有的变短了,这样字符串的长度才有可能大于原来的长度。
这里有两种情况:
1、这个块的长度为1,改变该字符后,与之相邻的块(左边的和右边的,如果有的话)和该块合成了一个块,长度变成了L(i-1)+L(i+1)+1,然后再平方。
2、该块的长度大于1,改变该块的最右边(或者最左边的字符)后,该块的长度变为了Li-1,该块右边的块(或者左边的块,如果有的话)的长度变为了L(i+1)+1;
分析以上两种情况,我们求出max{改变后的块的长度的平方 - 改变前的字符串的长度的平方},然后加上未改变的字符串的长度就行了。

代码:
#include<set>#include<map>#include<list>#include<queue>#include<stack>#include<cmath>#include<vector>#include<cstdio>#include<stdlib.h>#include<iostream>#include<string.h>#include<algorithm>using namespace std;#define pb(a) push_back(a)#define mp(a,b) make_pair(a,b)#define in(a) scanf("%d",&a)#define mm(a,b) memset(a,b,sizeof(a))#define out(a) printf("%d")#define MOD =1e9+7#define ll long long#define INF 0x3f3f3f3f#define FOR(i,l,r) for(int i=l;i<=r;i++)char s[100005];int n,cnt;long long sum,Max;long long num[100005];int main(){ int t; scanf("%d",&t); for(int cas=1;cas<=t;cas++){        scanf("%s",s);        n=strlen(s);        cnt=0;        int i=0,j=0;        while(i<=j&&j<n){            while(j<n&&s[j]==s[i])j++;            num[cnt++]=j-i;            i=j;        }        sum=0,Max=0;        for( i=0;i<cnt;i++)            sum+=num[i]*num[i];        for(i=1;i<cnt-1;i++){              if(num[i]==1){                long long NEW = (num[i-1]+num[i+1]+1)*(num[i-1]+num[i+1]+1);                long long OLD = num[i-1]*num[i-1]+1+num[i+1]*num[i+1];                if(NEW>OLD){                    Max = max(Max,NEW - OLD);                }              }        }        for(int i=0;i<cnt-1;i++){            long long NEW = (num[i]+1)*(num[i]+1)+(num[i+1]-1)*(num[i+1]-1);            long long OLD = num[i]*num[i]+(num[i+1])*(num[i+1]);            if(NEW>OLD){                Max=max(Max,NEW-OLD);            }        }        sum+=Max;        printf("Case #%d: %I64d\n",cas,sum);    }    return 0;}


1 0