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放右边更小,选一个小的输出
***/

最新文章

  1. Python正则表达式:最短匹配
  2. 【Java】Annotation_学习笔记
  3. python无意中发现的
  4. (转)JavaScript 中对变量和函数声明的“提前(hoist)”
  5. Mybatis中配置Mapper的方法
  6. 【转载】TCP协议疑难杂症全景解析
  7. 错误ERROR datanode.DataNode (DataXceiver.java:run(278)) - hadoop07:50010DataXceiver error processing unknown operation src:127.0.0.136479 dst:127.0.0.150010
  8. JavaScript中instanceof与typeof运算符的用法及区别详细解析
  9. Intellj Idea 2016.1.3的使用
  10. .NET 3.5(5) - LINQ查询操作符之Select、Where、OrderBy、OrderByDescending
  11. Objetive-C 中的相等比较
  12. 【多重背包】 poj 2392
  13. storm遇到问题汇总
  14. JS键盘事件对象之keyCode、charCode、which属性对比
  15. 将 MacOS 默认的 PHP 版本升级到 7.*
  16. Spring(转载二)
  17. mysql与cmd,中文乱码
  18. Markdown 使用技巧
  19. vue和stylus在subline中显示高亮
  20. Spring Boot + Spring Cloud 构建微服务系统(三):服务消费和负载(Feign)

热门文章

  1. 沈向洋|微软携手 OpenAI 进一步履行普及且全民化人工智能的使命
  2. HTML标签学习总结(2)
  3. 2、【Spark】Spark环境搭建(集群方式)
  4. MySQL集群MGR架构for单主模式
  5. Mysql8以上需要指定时区serverTimezone
  6. py基础之有序列表
  7. JZOJ 5286. 【NOIP2017提高A组模拟8.16】花花的森林 (Standard IO)
  8. FreeModBus源码解析(1)---开篇
  9. java套打快递单
  10. 峰哥说技术:02-第一个Spring Boot应用程序