Split a Number
time limit per test

2 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

Dima worked all day and wrote down on a long paper strip his favorite number nn consisting of ll digits. Unfortunately, the strip turned out to be so long that it didn't fit in the Dima's bookshelf.

To solve the issue, Dima decided to split the strip into two non-empty parts so that each of them contains a positive integer without leading zeros. After that he will compute the sum of the two integers and write it down on a new strip.

Dima wants the resulting integer to be as small as possible, because it increases the chances that the sum will fit it in the bookshelf. Help Dima decide what is the minimum sum he can obtain.

Input

The first line contains a single integer ll (2≤l≤1000002≤l≤100000) — the length of the Dima's favorite number.

The second line contains the positive integer nn initially written on the strip: the Dima's favorite number.

The integer nn consists of exactly ll digits and it does not contain leading zeros. Dima guarantees, that there is at least one valid way to split the strip.

Output

Print a single integer — the smallest number Dima can obtain.

Examples
input

Copy
7
1234567
output

Copy
1801
input

Copy
3
101
output

Copy
11
Note

In the first example Dima can split the number 12345671234567 into integers 12341234 and 567567. Their sum is 18011801.

In the second example Dima can split the number 101101 into integers 1010 and 11. Their sum is 1111. Note that it is impossible to split the strip into "1" and "01" since the numbers can't start with zeros.

题意:有一个数n,长度为l,l是n的位数有多少个,注意l最多有1e5(这是什么一个概念,long long 最多有18位,一开始我理解错题意了,就用long long写了)
要求将这个数n分割为2个没有前导0的正整数使得这2个正整数和最小

思路:注意到l最大有1e5,爆long long了,就祭出大数加法模板,现在就考虑怎么分的问题
怎样分才能让两个数之和最大?贪心地想是从中间开始分,但要考虑中间为0和长度为基数的情况,所以就要考虑是左边的数更长一点好还是右边的数更长一点好
先优先把mid选在右边,因为一个数的开头不能有前导0(单个0不算前导0),如果mid那一位为0,向右扩展mid,如果中间没有前导0且长度为基数,则会产生左右数长度不等的情况,所以要看mid这个数给左边能使他们两个之和更小还是给右边能使他们两个之和更小
现在默认mid放右边的数,从最高位依次判断两个数的大小如果左边的比右边的更小则把中间这个数给左边,使左边增加一位,右边减少一位,这样两个数之和是更小的,因为,左边那一位小于右边那一位了,左边增加的肯定是小于右边减少的,故能使整体之和更小,举个例子,123中间是2,现在默认给右边的,分开来就是1,23,现在来判断,1<2,则把中间那个给左边的数,变成12,3,现在发现,左边增加了11,右边减少了20,所以左边增加的小于右边减少的,那么总体是减少的
注意mid右边不能为0才能右移因为,不然就有前导0了,而如果左边的数大于右边的数,那么把中间这个数放右边是更优的
接下来优先把mid放左边,与上面同理,注意因为2次mid可能算的不一样,所以n1,n2记得要清0,不然可能会保留上一次的东西,一开始因为没清零WA了几次
最后判断是mid放左边更小还是mid放右边更小,选一个小的输出

 #include<bits/stdc++.h>
using namespace std;
const int amn=1e5+;
char in[amn],n1[amn],n2[amn];
int l,tp;
struct bignum{ ///大数加法的模板
int len,n[amn];
void getnum(char in[]){
len=strlen(in);
for(int i=;i<len;i++){
n[i]=in[len-i-]-'';
}
}
void add(bignum a,bignum b){
int le=max(a.len,b.len);
int x,c=;
len=;
for(int i=;i<le||c;i++){
x=c;
if(i<a.len)x+=a.n[i];
if(i<b.len)x+=b.n[i];
c=x/;
x%=;
n[i]=x;
len++;
}
}
int big(bignum a,bignum b){ ///比较大小
if(a.len>b.len)return ;
if(a.len<b.len)return -;
for(int i=a.len-;i>=;i--){
if(a.n[i]>b.n[i])return ;
if(a.n[i]<b.n[i])return -;
}
return ;
}
void out(){
for(int i=len-;i>=;i--){
printf("%c",n[i]+'');
}
printf("\n");
}
}a,b,c,d;
int fd(int x,int d){
int lx=x;
if(d) ///看现在要向左扩展还是向右扩展
while(in[x]==''&&x>=)x--; ///因为一个数的开头不能有前导0(单个0不算前导0)如果mid那一位为0,向左扩展mid
else
while(in[x]==''&&x<l)x++; ///如果mid那一位为0,向右扩展mid
if((x==l/)&&l%){ ///如果中间没有前导0且长度为基数,则会产生左右数长度不等的情况,所以要看mid这个数给左边能使他们两个之和更小还是给右边能使他们两个之和更小
for(int i=;i<=x;i++){ ///现在默认mid放右边的数
if(in[i]<in[i+x]){ ///从最高位依次判断两个数的大小如果左边的比右边的更小则把中间这个数给左边,使左边增加一位,右边减少一位,这样两个数之和是更小的,因为,左边那一位小于右边那一位了,左边增加的肯定是小于右边减少的,故能使整体之和更小,举个例子,123中间是2,现在默认给右边的,分开来就是1,23,现在来判断,1<2,则把中间那个给左边的数,变成12,3,现在发现,左边增加了11,右边减少了20,所以左边增加的小于右边减少的,那么总体是减少的
if(in[x+1]!='0')///mid右边不能为0才能右移因为,不然就有前导0了
x++;
break;
}
else if(in[i]>in[i+x]) break; ///如果左边的数大于右边的数,那么把中间这个数放右边是更优的
}
}
return x;
}
int main(){
ios::sync_with_stdio();
cin>>l>>in; ///怎样分才能让两个数之和最大?贪心地想是从中间开始分,但要考虑中间为0和长度为基数的情况,所以就要考虑是左边的数更长一点好还是右边的数更长一点好
int mid=fd(l/,); ///优先把mid选在右边
for(int i=;i<mid;i++)
n1[i]=in[i];
tp=;
for(int i=mid;i<l;i++)
n2[tp++]=in[i];
a.getnum(n1),b.getnum(n2);
c.add(a,b); ///大数加法,下面同理
mid=fd(l/,); ///优先把mid选在左边
memset(n1,,sizeof n1); ///因为2次mid可能算的不一样,所以n1,n2记得要清0,不然可能会保留上一次的东西
memset(n2,,sizeof n2);
for(int i=;i<mid;i++)
n1[i]=in[i];
tp=;
for(int i=mid;i<l;i++)
n2[tp++]=in[i];
a.getnum(n1),b.getnum(n2);
d.add(a,b);
if(a.big(c,d)<) ///选一个小的输出
c.out();
else
d.out();
}
/***
有一个数n,长度为l,l是n的位数有多少个,注意l最多有1e5(这是什么一个概念,long long 最多有18位,一开始我理解错题意了,就用long long写了)
要求将这个数n分割为2个没有前导0的正整数使得这2个正整数和最小
注意到l最大有1e5,爆long long了,就祭出大数加法模板,现在就考虑怎么分的问题
怎样分才能让两个数之和最大?贪心地想是从中间开始分,但要考虑中间为0和长度为基数的情况,所以就要考虑是左边的数更长一点好还是右边的数更长一点好
先优先把mid选在右边,因为一个数的开头不能有前导0(单个0不算前导0),如果mid那一位为0,向右扩展mid,如果中间没有前导0且长度为基数,则会产生左右数长度不等的情况,所以要看mid这个数给左边能使他们两个之和更小还是给右边能使他们两个之和更小
现在默认mid放右边的数,从最高位依次判断两个数的大小如果左边的比右边的更小则把中间这个数给左边,使左边增加一位,右边减少一位,这样两个数之和是更小的,因为,左边那一位小于右边那一位了,左边增加的肯定是小于右边减少的,故能使整体之和更小,举个例子,123中间是2,现在默认给右边的,分开来就是1,23,现在来判断,1<2,则把中间那个给左边的数,变成12,3,现在发现,左边增加了11,右边减少了20,所以左边增加的小于右边减少的,那么总体是减少的
注意mid右边不能为0才能右移因为,不然就有前导0了,而如果左边的数大于右边的数,那么把中间这个数放右边是更优的
接下来优先把mid放左边,与上面同理,注意因为2次mid可能算的不一样,所以n1,n2记得要清0,不然可能会保留上一次的东西,一开始因为没清零WA了几次
最后判断是mid放左边更小还是mid放右边更小,选一个小的输出
***/

Codeforces Round #567 (Div. 2) B. Split a Number的更多相关文章

  1. Codeforces Round #567 (Div. 2)B. Split a Number (字符串,贪心)

    B. Split a Number time limit per test2 seconds memory limit per test512 megabytes inputstandard inpu ...

  2. DP+埃氏筛法 Codeforces Round #304 (Div. 2) D. Soldier and Number Game

    题目传送门 /* 题意:b+1,b+2,...,a 所有数的素数个数和 DP+埃氏筛法:dp[i] 记录i的素数个数和,若i是素数,则为1:否则它可以从一个数乘以素数递推过来 最后改为i之前所有素数个 ...

  3. 数学+DP Codeforces Round #304 (Div. 2) D. Soldier and Number Game

    题目传送门 /* 题意:这题就是求b+1到a的因子个数和. 数学+DP:a[i]保存i的最小因子,dp[i] = dp[i/a[i]] +1;再来一个前缀和 */ /***************** ...

  4. Codeforces Round #567 (Div. 2)自闭记

    嘿嘿嘿,第一篇文章,感觉代码可以缩起来简直不要太爽 打个div2发挥都这么差... 平均一题fail一次,还调不出错,自闭了 又一次跳A开B,又一次B傻逼错误调不出来 罚时上天,E还傻逼了..本来这场 ...

  5. Codeforces Round #567 (Div. 2)A

    A. Chunga-Changa 题目链接:http://codeforces.com/contest/1181/problem/A 题目 Soon after the Chunga-Changa i ...

  6. Codeforces Round #514 (Div. 2) E. Split the Tree(倍增+贪心)

    https://codeforces.com/contest/1059/problem/E 题意 给出一棵树,每个点都有一个权值,要求你找出最少条链,保证每个点都属于一条链,而且每条链不超过L个点 和 ...

  7. Codeforces Round #567 (Div. 2) E2 A Story of One Country (Hard)

    https://codeforces.com/contest/1181/problem/E2 想到了划分的方法跟题解一样,但是没理清楚复杂度,很难受. 看了题解觉得很有道理,还是自己太菜了. 然后直接 ...

  8. Codeforces Round #567 Div. 2

    A:签到. #include<bits/stdc++.h> using namespace std; #define ll long long #define inf 1000000010 ...

  9. Codeforces Round #567 (Div. 2) A.Chunga-Changa

    原文链接:传送 #include"algorithm" #include"iostream" #include"cmath" using n ...

随机推荐

  1. 查漏补缺:OSI七层模型和TCP/IP模型

    应用层协议:Telnet.FTP.e-mail等 传输层协议:TCP.UDP.STCP等 网络层协议:IP.ICMP.IGMP等 链路层协议:设备驱动及接口卡

  2. Linux上centOs6+安装mysql5.7详细教程 - 前端小鱼塘

    https://coyhom.github.io/ 人类的本质是复读机,作为一个非linux专业人员学习linux最好的办法是重复 环境centos6.5 版本5.7 1: 检测系统是否自带安装mys ...

  3. C++走向远洋——47(第十二周、运算符重载基础程序、阅读)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  4. PyMuPDF库(处理PDF)

    昨天在公司需要把一份PDF格式认证表转换为图片JPEG格式,所以在网上查询了一些与此相关的python库,最后看网上大多都是使用Wand和PyMuPDF,在安装了Wand库后,导入相应的模块后报错了, ...

  5. 网络编程模型(C/S模型和B/S模型)

    目录 网络应用编程模型 互联网与企业内部网 早期计算机网络的通信模型 C/S模式 B/S模式 B/S 和 C/S 的区别 网络应用编程模型 互联网与企业内部网 网络的两个含义: 互联网 :互联网(In ...

  6. handlebar.js模板引擎(轻页面小工程可用)

    介绍 Handlebars 让你能够有能力高效地容易地创立语义化的模版.Handlebars兼容Mustache语法,在大多数情况下它可以读取Mustache的语法并在你当前模板中使用.具体点击这里 ...

  7. .NET Core 获取主机运行资源的库

    简介 CZGL.SystemInfo 是一个支持 Windows 和 Linux 的资源信息获取库,用于获取系统环境.机器资源信息.系统资源使用情况. Nuget 搜索 CZGL.SystemInfo ...

  8. python装饰器之函数作用域

    1.函数作用域LEGB L:local函数内部作用域 E:enclosing函数内部与内嵌函数之间 G:global全局作用域 B:build-in内置作用域 passline = 60 def fu ...

  9. vue项目开发,用webpack配置解决跨域问题

    今天在本地开发时候碰到了跨域的问题,突然觉着跨域问题在所难免啊,之前没有没有碰到总觉着解决跨域很高大上的样纸,其实就是受限于网络的同源策略,跨域前后端都可以进行处理. 1,后端更改header hea ...

  10. nes 红白机模拟器 第2篇 InfoNES

    InfoNES 支持 map ,声音,代码比较少,方便 移值. 在上个 LiteNES  的基础上,其实不到半小时就移值好了这个,但问题是,一直是黑屏.InfoNES_LoadFrame ()  Wo ...