2017.10.14NOIP初赛上机测试
来源:互联网 发布:绵阳cnc编程招聘 编辑:程序博客网 时间:2024/06/05 16:53
Problem 1 :
题目描述
今年开始上学的 DQS 非常喜欢石子, 她总是会收集很多不同类型的石子来卖钱, 这个世界的石子只有两种——蓝色和白色(用01 表示) 并且都是连在一起的, 不能移动, 因此 DQS 只好使用她的神力来解除石子不能移动的封印, 但是由于某些原因 DQS 希望让自己消耗更多的神力, 因此她许愿黑暗之神让她可以转换连在一起的石子中的一颗。 消耗的神力计算方法为这一串石子中相邻相同的石子个数的平方和。 DQS 想知道, 如何改变其中一个石子的种类, 使得整个石子串的消耗最大(含多组数据)
输入描述 一个数 T接下来 T 行, 每行一个长度为 N 的 01 串
输出描述 一个数 p 表示 DQS 消耗的神力
样例输入
2
000011
0101
样例输出
26
10
数据范围及提示
1<=T<=50
60%:1<=N<=1000
100%:1<=N<=100000
思路
处理出初始答案(不进行修改)和连续的0|1区间范围,尝试将每一个元素修改求出当前消耗总和,对于不在区间边缘的元素可以忽略。
代码
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#define RI register intusing namespace std;int t,len,tot;int pos[100010];//属于哪一个区间 long long sum,ans,tmp,ans1;bool bs[100010],bt[100010];//左边,右边 string num;struct inte{ int ans1,ans2;}l[100010];//点 struct ren{ int l,r;}p[100010];//区间 int main(){ scanf("%d",&t); for(RI i=1;i<=t;i++) { memset(bs,0,sizeof(bs)); memset(bt,0,sizeof(bt)); memset(l,0,sizeof(l));//初始化注意 cin>>num; len=num.length(); sum=1; ans=0; for(RI i=0;i<len-1;i++)//预处理初始答案 { if(num[i]==num[i+1]) sum++; else { ans+=sum*sum; sum=1; } } ans+=sum*sum; ans1=ans; if(num[0]!=num[1])//确定每一位置是否为相同元素区间的开始和结束位置(左右是否不同) bt[0]=1; for(RI i=1;i<len-1;i++) { if(num[i]!=num[i-1]) bs[i]=1; if(num[i]!=num[i+1]) bt[i]=1; } if(num[len-1]!=num[len-2]) bs[len-1]=1; tot=1; p[tot].l=0; for(RI i=0;i<len;i++)//处理每个区间长度 { //不可以直接选取使最大区间最大的方案,因为周边区间的消耗也会变化影响答案 pos[i]=tot; if(bs[i]) { p[tot].l=i; for(int j=i-1;j>=0;j--) { if(num[j]==num[i]) break; l[i].ans1++; } } if(bt[i]) { p[tot++].r=i; for(int j=i+1;j<len;j++) { if(num[j]==num[i]) break; l[i].ans2++; } } } if(bs[len-1]) { p[tot].l=p[tot].r=len-1; } else p[tot].r=len-1; tmp=0; for(RI i=0;i<len;i++)//枚举每个位为改变的位置 { if(!bs[i]&&!bt[i]) continue; if(bs[i]&&bt[i])//计算此时答案 { tmp=ans-(l[i].ans1*l[i].ans1)-(l[i].ans2*l[i].ans2)+((l[i].ans1+l[i].ans2+1)*(l[i].ans1+l[i].ans2+1))-1; } if(bs[i]&&!bt[i]) { tmp=ans-(l[i].ans1*l[i].ans1)-((p[pos[i]].r-p[pos[i]].l+1)*(p[pos[i]].r-p[pos[i]].l+1))+((l[i].ans1+1)*(l[i].ans1+1))+((p[pos[i]].r-p[pos[i]].l)*(p[pos[i]].r-p[pos[i]].l)); } if(!bs[i]&&bt[i]) { tmp=ans-(l[i].ans2*l[i].ans2)-((p[pos[i]].r-p[pos[i]].l+1)*(p[pos[i]].r-p[pos[i]].l+1))+((l[i].ans2+1)*(l[i].ans2+1))+((p[pos[i]].r-p[pos[i]].l)*(p[pos[i]].r-p[pos[i]].l)); } ans1=max(ans1,tmp); } printf("%lld\n",ans1); } return 0;}
阅读全文
1 0
- 2017.10.14NOIP初赛上机测试
- 【NOIP初赛】 计算机硬件
- 【NOIP初赛】 网络相关
- 【NOIP初赛】 杂碎知识点
- 【NOIP初赛】 组合数学
- [NOIP初赛知识点汇总]
- noip初赛冒个泡
- NOIP初赛总复习
- NOIP初赛相关代码
- NOIP初赛知识
- 对于NOIP初赛感想
- *TEST 6 for NOIP + NOIP初赛
- NOIP初赛复习资料(全)
- NOIP初赛准备:第一课时
- NOIP初赛准备:第二课时
- NOIP初赛准备:第三课时
- NOIP初赛准备:第四课时
- 【NOIP初赛】 软件与操作系统
- 伪类before和after
- 五个简单的工具类
- android 简单的文字生成二维码
- ubuntu 使用笔记 :
- python中如何对类的成员函数开启线程
- 2017.10.14NOIP初赛上机测试
- 存储引擎特点及选择
- 查看linux系统常用的命令,Linux查看系统配置常用命令
- linux中service命令的原理
- IOS中UIimageView的内容模式
- [mongoDB]exception in initAndListen: 20 Attempted to create a lock file on a read-only directory:
- Windonws 与 Ubuntu 下Python3.6安装Scrapy的快捷方法
- Beyond Compare如何比较两个文件夹差异
- 《利用python进行数据分析》ch04