CF1181 B. Split a Number

题目传送门:https://codeforces.com/problemset/problem/1181/B

题目大意:
给定一串长为 $ l(l\leqslant10^5) $ 的数字,可将数字分成无前导零的两个数\(A,B\),问\(A+B\)的最小值


将数字分成长度相等的两部分显然是最优的,我们只需要判断是否有前置零,将断点前移或后移判断即可

/*program from Wolfycz*/
#include<map>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Fi first
#define Se second
#define ll_inf 1e18
#define MK make_pair
#define sqr(x) ((x)*(x))
#define pii pair<int,int>
#define int_inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline char gc(){
	static char buf[1000000],*p1=buf,*p2=buf;
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
template<typename T>inline T frd(T x){
	int f=1; char ch=gc();
	for (;ch<'0'||ch>'9';ch=gc())	if (ch=='-')    f=-1;
	for (;ch>='0'&&ch<='9';ch=gc())	x=(x<<1)+(x<<3)+ch-'0';
	return x*f;
}
template<typename T>inline T read(T x){
	int f=1; char ch=getchar();
	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')	f=-1;
	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
	return x*f;
}
inline void print(int x){
	if (x<0)	putchar('-'),x=-x;
	if (x>9)	print(x/10);
	putchar(x%10+'0');
}
const int digit=8;
const int base=1e8;
const int maxn=2e4;
char s[maxn*digit],temp[maxn*digit];
struct Bignum{
	int V[maxn],len;
	Bignum(){len=1,memset(V,0,sizeof(V));}
	void read(char *s){
		int l=strlen(s),tim=1;
		reverse(s,s+l); len=(l-1)/digit+1;
		for (int i=0;i<l;i++){
			V[i/digit]+=tim*(s[i]-'0'),tim*=10;
			if (tim==base)	tim=1;
		}
		reverse(s,s+l);
	}
	void print(){
		printf("%d",V[len-1]);
		for (int i=len-2;~i;i--)	printf("%0*d",digit,V[i]);
		putchar('\n');
	}
}Ans;
Bignum operator +(Bignum x,Bignum y){
	Bignum z; z.len=max(x.len,y.len);
	for (int i=0;i<=z.len;i++)	z.V[i]+=x.V[i]+y.V[i],z.V[i+1]+=z.V[i]/base,z.V[i]%=base;
	while (z.V[z.len])	z.V[z.len+1]+=z.V[z.len]/base,z.V[z.len]%=base,z.len++;
	return z;
}
bool operator <(Bignum x,Bignum y){
	if (x.len!=y.len)	return x.len<y.len;
	for (int i=x.len;~i;i--)	if (x.V[i]!=y.V[i])	return x.V[i]<y.V[i];
	return 0;
}
int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	int n=read(0);
	scanf("%s",s); Ans.read(s);
	memcpy(temp,s,sizeof(s));
	for (int pos=n>>1;pos>0;pos--){
		if (temp[pos]=='0')	continue;
		Bignum A; A.read(temp+pos);
		temp[pos]='\0';
		Bignum B; B.read(temp);
		if (A+B<Ans)	Ans=A+B;
		temp[pos]=s[pos];
		break;
	}
	for (int pos=(n>>1)+1;pos<n;pos++){
		if (temp[pos]=='0')	continue;
		Bignum A; A.read(temp+pos);
		temp[pos]='\0';
		Bignum B; B.read(temp);
		if (A+B<Ans)	Ans=A+B;
		temp[pos]=s[pos];
		break;
	}
	Ans.print();
	return 0;
}
posted @ 2021-07-08 10:12  Wolfycz  阅读(50)  评论(0编辑  收藏  举报