CF1181B


題面

主要思想

很明顯,題面就是讓你將一串數割開,使得隔開后的兩數總和最小。

稍微分析一下后我們會想到:對於這里隔開后的兩個數,他們的總位數一定,顯然他們的位數越相近,總和就有機會越小。所以我們嘗試從這串數的正中央着手割開,使用高精度進行操作。

我們從這串數的最中央開始分割,先嘗試向左移動,找到該過程中第一個符合題意要求的方案,記錄結果。然后再嘗試向右移動,再找到該過程中第一個符合題意要求的方案,記錄下來。最后比較兩結果,取較小者。

本文中使用雙端隊列模擬高精度,使用較為便利。

代碼

#pragma GCC optimize ("O2")
#pragma G++ optimize ("O2")
#include <bits/stdc++.h>
using namespace std;

#define QUICK

#ifdef QUICK
	#define R register
#else
	#define R 
#endif

//定義輸出deque高精度的方法
ostream& operator << (ostream &out,deque<int>& x)
{
	for (R deque<int>::iterator it=x.begin();it!=x.end();it++)
	{
		out<<char(*it+'0');
	}
	out<<std::endl;
	return out;
};


int main()
{
#ifdef QUICK
	ios::sync_with_stdio(false);//流加速
#endif
	deque<int> a,b,s,c,d,n;
   	//a,b存放第一次割法的前后者情況
   	//c,d存放第二次割法的前后者情況
   	//s,n分別存放兩次割法的和
	int l;
	cin>>l;
	for (R int point=1;point<=l;point++)
	{
		char t;
		cin>>t;
		if(point<=l/2)
		{
			a.push_back(t-'0');
			c.push_back(t-'0');
		}//前半段數
		else
		{
			b.push_back(t-'0');
			d.push_back(t-'0');
		}//后半段數
	}
	a.push_back(b.front());
	b.pop_front();
	a.push_back(b.front());
	b.pop_front();
	d.push_front(c.back());
	c.pop_back();
    	//向左搜索
	while(!a.empty())
	{
		b.push_front(a.back());
		a.pop_back();
		if(a.empty()||b.empty()||a.front()==0||b.front()==0)
		{//判斷為空或是前綴0
			continue;
		}
		deque<int>::reverse_iterator pa=a.rbegin(),pb=b.rbegin();
     		//反向迭代器
		int g=0;
       		//相加
		for(;pa!=a.rend()&&pb!=b.rend();++pa,++pb)
		{
			s.push_front((*pa+*pb+g)%10);
			g=(*pa+*pb+g)/10;
		}
		while(pa!=a.rend())
		{
			s.push_front((*pa+g)%10);
			g=(*pa+g)/10;
			pa++;
		}
		while(pb!=b.rend())
		{
			s.push_front((*pb+g)%10);
			g=(*pb+g)/10;
			pb++;
		}
		if(g!=0)
		{
			s.push_front(g);
		}
		break;
	}	
    	//向右搜索
	while(!d.empty())
	{
		c.push_back(d.front());
		d.pop_front();
		if(c.empty()||d.empty()||c.front()==0||d.front()==0)
		{
			continue;
		}
		deque<int>::reverse_iterator pc=c.rbegin(),pd=d.rbegin();
		int g=0;
		for(;pc!=c.rend()&&pd!=d.rend();++pc,++pd)
		{
			n.push_front((*pc+*pd+g)%10);
			g=(*pc+*pd+g)/10;
		}
		while(pc!=c.rend())
		{
			n.push_front((*pc+g)%10);
			g=(*pc+g)/10;
			pc++;
		}
		while(pd!=d.rend())
		{
			n.push_front((*pd+g)%10);
			g=(*pd+g)/10;
			pd++;
		} 
		if(g!=0)
		{
			n.push_front(g);
		}
		break;
	}
//	cout<<a<<b<<c<<d<<s<<n;
	//判斷s與n的大小,取小者輸出
	if(s.size()==0) 
	{
		cout<<n<<std::endl;
		return 0;
	}
	if(n.size()==0)
	{
		cout<<s<<std::endl;
		return 0;
	}
	if(s.size()!=n.size())
	{
		if(s.size()<n.size())
		{
			cout<<s<<std::endl;
		} 
		else
		{
			cout<<n<<std::endl;
		}
		return 0;
	}
	else
	{//逐位判斷
		deque<int>::iterator ps=s.begin(),pn=n.begin();
		for(;ps!=s.end()&&pn!=n.end();ps++,pn++)
		{
			if(*pn!=*ps)
			{
				if(*ps<*pn)
				{
					cout<<s<<std::endl;
				} 
				else
				{
					cout<<n<<std::endl;
				}
				return 0;
			} 
		}
	}
	cout<<n<<std::endl;
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM