CF1181B Split a Number

分割数字串求最小和
本文介绍了一种解决特定数学问题的算法,即如何分割一个长数字串使其两部分的和最小。通过从中间分割并左右移动寻找最优解,利用双端队列实现高精度计算。文章详细解释了算法思路,并提供了完整的代码实现。

题面

主要思想

很明显,题面就是让你将一串数割开,使得隔开后的两数总和最小。

稍微分析一下后我们会想到:对于这里隔开后的两个数,他们的总位数一定,显然他们的位数越相近,总和就有机会越小。所以我们尝试从这串数的正中央着手割开,使用高精度进行操作。

我们从这串数的最中央开始分割,先尝试向左移动,找到该过程中第一个符合题意要求的方案,记录结果。然后再尝试向右移动,再找到该过程中第一个符合题意要求的方案,记录下来。最后比较两结果,取较小者。

本文中使用双端队列模拟高精度,使用较为便利。

代码

#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;
}

转载自本人Luogu Blog这篇文章

这是一道crypto题目,背景是二战期间,在布莱切利园工作的你主要负责破译轴心国的电子密文。一天下午,你成功截获了一段加密信号并记录了下来: 1.信号在接收到第六个“5”后有明显的电流声,可能是对前面密文的补充 提示是本涉及的编码(区别编码和加密)方式仅为Base64和Hex.flag形式为flag{×××××}(保留空格,全部小写) 给了一个文本,是626e52324947647065475a766458427162793132626e6c30625770796247677572dc9f843ec35f46a3b6003c95ad011ae6b8e12e5e2c2df2e3e2b92321a0b59cd5e6e4bbdb6e3222024b91b2c0c5ee678f928e41babed98cc26b855645605342a483e0b761c42db1bc04843a7a73dcaba515efdd67247ef18ddede4da32a4f097703e16f848e10b0a94edc9dcda0676890701c931fcb96335c9f7cf4fe2d757190d859bb8804d28d978d740f9f3c13aa44dbcc5ca1cbbfabfc332952b2112680eaef54ecc6f668f9d70f63a7229c9d8284b88ebef1cd3c42fa3c5274549729712c880c509ce86975689370f7081200481945b188b4bc7150a4a3a7bec9d8b798684b775daf4c0fcf1534bdd948bb13c1 其中第六个5之后的72dc9f843ec35f46a3b6003c95ad011ae6b8e12e5e2c2df2e3e2b92321a0b59cd5e6e4bbdb6e3222024b91b2c0c5ee678f928e41babed98cc26b855645605342a483e0b761c42db1bc04843a7a73dcaba515efdd67247ef18ddede4da32a4f097703e16f848e10b0a94edc9dcda0676890701c931fcb96335c9f7cf4fe2d757190d859bb8804d28d978d740f9f3c13aa44dbcc5ca1cbbfabfc332952b2112680eaef54ecc6f668f9d70f63a7229c9d8284b88ebef1cd3c42fa3c5274549729712c880c509ce86975689370f7081200481945b188b4bc7150a4a3a7bec9d8b798684b775daf4c0fcf1534bdd948bb13c1 题目提供给我KEY和IV我通过cbc解出来内容是The number of models is the same as that of Tesla's midsize sedan models. Damn it, the order of the letters (A-F) is the same as the CET options. 我该怎么得到flag?
最新发布
10-06
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值