Kingdom of Black and White

                                                                                                           Time Limit: 2000/1000
MS (Java/Others)   

                                                                                                        Memory Limit: 65536/65536
K (Java/Others)

                                                                                          Total Submission(s): 1201    Accepted Submission(s): 374

->   Link 
 <-

看到这提交记录了吧,我活生生的拉低了通过率,都不造自己怎么想的,整整两天没A其他的题,就是死咬这道题,思路很早就有了,死活WA,终于在第三天中午浪费了一个午休搞出来了,不过参考了一下网上的博客,思路都差不多,还是有值得借鉴的地方,然后发现了一个坑点(就是跪在这两天),也发现了HDU上测试数据的问题;发了这么多时间还是有收获的;

题意:开始看了好久还看不懂,也不造求啥,后来分析样例明白了,就是给定的一个01串,求连续相同的字符的长度的平方和就是答案,然后现在可以改变一个字符,问这个值最大是?看样例,4个0,2个1,值就是4*4+2*2=20,改变一个字符很明显将与0相隔的那个1改成0,这样就是5个0,1个1,值为5*5+1*1=26;明白了吧;

思路: 一开始以为是个区间dp问题,后来问学长,其实就是把字符串压缩,只留下数量,比如上面的4 2,5 1这样的,然后改变一个使得平方和最大,我们来看,如果有长度有1,则可以合并左右 ,否则,从当前子串的左边或者右边改变一个,这样,当前的子串长度就加1,再与最大值 进行比较;

来看AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N=100000+10;
char s[N];
long long a[N],b[N];注意这里数据范围,就是跪在这里了;
int main()
{
int t,i,x;
scanf("%d",&t);
int t1=t;
while(t--)
{
scanf("%s",s);
x=strlen(s);
printf("Case #%d: ",t1-t);
if(x<4)
{
printf("%d\n",x*x);
continue;
}
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
int j=1,k=0;
for(i=1; i<=x; i++)
{
if(s[i]==s[i-1])
j++;
else
{
a[k++]=j;//压缩;
j=1;
}
}
long long maxx=0;
for(i=0; i<k; i++)
b[i]=b[i-1]+a[i]*a[i];//累加起来,当改变某一小片段时左边和右边平方和是不变的;
long long max1=b[k-1];
for(i=0; i<k; i++)
if(a[i]==1)//当其为1时左右可以一起合并(恰好改变本身)
{
maxx=(a[i]+a[i-1]+a[i+1])*(a[i]+a[i-1]+a[i+1])+b[i-2];
if(i<k-1)//注意边界问题;
maxx+=b[k-1]-b[i+1];
max1=max(max1,maxx);
}
maxx=0;
for(i=0; i<k-1; i++)//往左合并一个;
{
maxx=(a[i]+1)*(a[i]+1)+(a[i+1]-1)*(a[i+1]-1)+b[i-1]+(b[k-1]-b[i+1]);
max1=max(max1,maxx);
}
for(i=1; i<k; i++)//往右合并一个;
{
maxx=(a[i]+1)*(a[i]+1)+(a[i-1]-1)*(a[i-1]-1)+b[i-2]+(b[k-1]-b[i]);
max1=max(max1,maxx);
}
printf("%I64d\n",max1);
}
return 0;
}

网上看的一个更简洁一点的思路(有所补充):AC

#include<bits/stdc++.h>
using namespace std;
const int N=100000+10;
char s[N];
long long a[N];
int main()
{
int t,x,i;
scanf("%d",&t);
int t1=t;
while(t--)
{
scanf("%s",s);
x=strlen(s);
i=0;
int j=0,k=0;
while(i<=j&&j<x)//压缩这里优化了一下;
{
while(j<x&&s[i]==s[j]) j++;
a[k++]=j-i;
i=j;
}
long long sum=0,maxx=0;
for(i=0;i<k;i++)
sum+=a[i]*a[i];//直接将未改变的值算出来,然后改变的话只需看增大了多少,加上即可;
for(i=1;i<k-1;i++)
if(a[i]==1)
{
long long neW=(a[i-1]+a[i+1]+1)*(a[i-1]+a[i+1]+1);//改变本身;
long long old=(a[i-1]*a[i-1])+a[i+1]*a[i+1]+1;//未改变的;
if(neW>old)
maxx=max(maxx,neW-old);
}
for(i=0;i<k-1;i++)//往左合并一个,如000011-->000001;
{
long long neW=(a[i]+1)*(a[i]+1)+(a[i+1]-1)*(a[i+1]-1);
long long old=a[i]*a[i]+a[i+1]*a[i+1];
if(neW>old)
maxx=max(maxx,neW-old);
}
for(i=1;i<k;i++)//往右合并一个(原代码没有这一块,但实际会出错,如1110000011,最大应输出46,而未考虑这种情况则输出44,但HDU上竟然过了,可见其测试数据之水)
{
long long neW=(a[i]+1)*(a[i]+1)+(a[i-1]-1)*(a[i-1]-1);
long long old=a[i]*a[i]+a[i-1]*a[i-1];
if(neW>old)
maxx=max(maxx,neW-old);
}
printf("Case #%d: ",t1-t);
printf("%I64d\n",sum+maxx);
}
return 0;
}

实力还是不行,学长秒有思路,然而我却以为是区间DP,思路就错了好久,然而思路正确却还是卡了两天,实在太弱!

HDU-5583-Kingdom of Black and White(2015ACM/ICPC亚洲区上海站-重现赛)的更多相关文章

  1. HDU-5532//2015ACM/ICPC亚洲区长春站-重现赛-F - Almost Sorted Array/,哈哈,水一把区域赛的题~~

    F - Almost Sorted Array Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & ...

  2. HDU 5131.Song Jiang's rank list (2014ACM/ICPC亚洲区广州站-重现赛)

    Song Jiang's rank list Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java ...

  3. hdu 5583 Kingdom of Black and White(模拟,技巧)

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

  4. hdu 5583 Kingdom of Black and White

    Kingdom of Black and White Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja ...

  5. HDU 5583 Kingdom of Black and White 水题

    Kingdom of Black and White Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showpr ...

  6. 2015ACM/ICPC亚洲区上海站

    5573 Binary Tree(构造) 题意:给你一个二叉树,根节点为1,子节点为父节点的2倍和2倍+1,从根节点开始依次向下走k层,问如何走使得将路径上的数进行加减最终结果得到n. 联想到二进制. ...

  7. HDU 5583 Kingdom of Black and White(暴力)

    http://acm.hdu.edu.cn/showproblem.php?pid=5583 题意: 给出一个01串,现在对这串进行分组,连续相同的就分为一组,如果该组内有x个数,那么就对答案贡献x* ...

  8. HDU 5112 A Curious Matt (2014ACM/ICPC亚洲区北京站-重现赛)

    A Curious Matt Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) ...

  9. HDU 5127.Dogs' Candies-STL(vector)神奇的题,set过不了 (2014ACM/ICPC亚洲区广州站-重现赛(感谢华工和北大))

    周六周末组队训练赛. Dogs' Candies Time Limit: 30000/30000 MS (Java/Others)    Memory Limit: 512000/512000 K ( ...

随机推荐

  1. ZooKeeper通过ACL修复未授权访问漏洞

    默认情况下ZooKeeper允许匿名访问,因此在安全漏洞扫描中暴漏未授权访问漏洞. 一.参考资料 <ZooKeeper 笔记(5) ACL(Access Control List)访问控制列表& ...

  2. SpringCloud开发学习总结(七)—— 声明式服务调用Feign(一)

    在实践的过程中,我们会发现在微服务架构中实现客户端负载均衡的服务调用技术Spring Cloud Ribbon<SpringCloud开发学习总结(四)—— 客户端负载均衡Ribbon> ...

  3. JDBC基础学习

    1.概念:java数据库连接技术 2.JDBC:是一个规范,提供接口(面向接口编程) 3.JDBC API:提供程序员调用的接口和类,集成在java.sql 和javax.sql包中.如:Driver ...

  4. 原型模式及php实现

    原型模式: 通过复制已经存在的实例来返回新的实例,而不是新建实例,并且原型(被复制的实例)是可定制的:原型模式多用于创建复杂的或耗时的实例,这种情况下,复制一个已经存在的实例是程序运行更高效无疑是一种 ...

  5. mysql 忘记密码 登陆+修改密码

    step1: 苹果->系统偏好设置->最下边点mysql 在弹出页面中 关闭mysql服务(点击stop mysql server) step2: 进入终端输入:cd /usr/local ...

  6. IPython notebook快捷键(Jupyter notebook)

    转自“https://blog.csdn.net/eswai/article/details/53642802” 本文整理了神器IPython Notebook(或Jupyter Notebook)的 ...

  7. spring jdbc 批处理插入主健重复的数据

    1.有事务:当调用spring jdbc 的批处理的时候,在实现层加入事物,只要有插入异常的数据,整个批处理操作都会回滚.事务保证操作的原子性. 2.无事务:当没有事务的时候,批处理插入数据的时候,若 ...

  8. R Programming week2 Functions and Scoping Rules

    A Diversion on Binding Values to Symbol When R tries to bind a value to a symbol,it searches through ...

  9. Quartz2D知识点聚合案例

    Quartz2D知识点聚合 基本 //画图片 UIImage *image = [UIImage imageNamed:@"阿狸头像"]; [image drawInRect:re ...

  10. raw cannot be resolved or is not a field解决办法

    解决raw文件夹问题 查看左侧项目/res文件夹下是否有raw文件夹,(一定是放到res文件夹下,raw在项目开始创建时候不会自动创建,所以要自己创建)