CF1330B题解
题意:
给定一个长为 \(n\) 序列 \(a\) ,问是否能分成两个排列,并输出方案
(排列:从 \(1—n\) 中选取不同的 \(n\) 个元素组成的序列)
思路:
观察数据范围可以猜出,这题 \(O(n)\) 能解决;
因为两个排列是不重叠的,所以可以考虑分别枚举 \(a_1—a_l\) 是否能组成 \(1—l\) 的排列,\(a_{l+1}—a_n\) 是否能构成排列,那么就用 \(l_i\) 表示 前\(i\) 个数是否能形成一个排列,\(r_i\) 表示后 \(i\) 个数是否能形成排列,当 \(l_i\) 与 \(r_{i+1}\) 同时为真的时候可行,输出 \(i\) 和 \(n-i\) 即可;
此题还有一个重要的难题,就是如何判断是一个排列:
比如判断前 \(i\) 个数是否为排列
- 必然有前 \(i\) 个数的最大值为 \(i\) ;
- 任意小于 \(i\) 的数出现且只出现一次;
当上面两条都成立时必然为一个排列,具体实现见代码。
尽管以上已经为 \(O(n)\) 的可行算法,但是为了实现方便,可以加一些优化:
- 因为要分成两个排列,所以序列 \(a\) 的最大值 \(maxn\) 必然在一个排列中,\(n-maxn\) 必然存在与另一个排列中,所以一个排列的长度为 \(maxn\),另一个为 \(n-maxn\) ,这说明了最多只存在两种方案; 
- 因为最多只有两种方案,所以若某一数字出现两次以上,必然不存在方案。 
代码:
cin>>t;
while(t--)
{
	memset(vis,0,sizeof(vis));
	memset(l,0,sizeof(l));
	memset(r,0,sizeof(r));
	cin>>n;
	for(int i=1;i<=n;i++)	cin>>a[i];
	int num=0,maxx=0;
	for(int i=1;i<=n;i++)
	{
		maxx=max(maxx,a[i]);
		if(vis[a[i]])	continue;
		if(a[i]<=maxx)
			vis[a[i]]=1,num++;
		if(num==maxx&&num==i)	l[i]=true;
	}
	num=0,maxx=0;
	for(int i=n;i>=1;i--)
	{
		maxx=max(maxx,a[i]);
		if(vis[a[i]])	continue;
		if(a[i]<=maxx)
			vis[a[i]]=1,num++;
		if(num==maxx&&num==(n-i+1))	r[i]=true;
	}
	memset(vis,0,sizeof(vis));
	int ans=0;
	for(int i=1;i<=n-1;i++)
		if(l[i]&&r[i+1])	ans++;
	cout<<ans<<endl;
	for(int i=1;i<=n-1;i++)
		if(l[i]&&r[i+1])	cout<<i<<" "<<n-i<<endl;
}
CF1330B题解的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
		我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ... 
- noip2016十连测题解
		以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ... 
- BZOJ-2561-最小生成树 题解(最小割)
		2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ... 
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
		Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ... 
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
		题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ... 
- 2016ACM青岛区域赛题解
		A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ... 
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
		http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ... 
- 网络流n题 题解
		学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ... 
- CF100965C题解..
		求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ... 
随机推荐
- 图像分类:CVPR2020论文解读
			图像分类:CVPR2020论文解读 Towards Robust Image Classification Using Sequential Attention Models 论文链接:https:// ... 
- CVPR2020论文解析:视频语义检索
			CVPR2020论文解析:视频语义检索 Fine-grained Video-Text Retrieval with Hierarchical Graph Reasoning 论文链接:https:/ ... 
- MIT Graph实践概述
			MIT Graph实践概述 Features功能 • iCloud Support • Multi Local & Cloud Graphs • Thread Safe • S ... 
- Linux内存技术分析(上)
			Linux内存技术分析(上) 一.Linux存储器 限于存储介质的存取速率和成本,现代计算机的存储结构呈现为金字塔型.越往塔顶,存取效率越高.但成本也越高,所以容量也就越小.得益于程序访问的局部性原理 ... 
- CVPR2020:点云分析中三维图形卷积网络中可变形核的学习
			CVPR2020:点云分析中三维图形卷积网络中可变形核的学习 Convolution in the Cloud: Learning Deformable Kernels in 3D Graph Con ... 
- STM32使用DMA发送串口数据
			1.概述 上一篇文章<STM32使用DMA接收串口数据>讲解了如何使用DMA接收数据,使用DMA外设和串口外设,使用的中断是串口空闲中断.本篇文章主要讲解使用DMA发送数据,不会讲解基础的 ... 
- 【C++】解决c++中cout输出中文乱码问题
			问题:cout输出中文乱码.例如下面的代码输出会乱码. cout << "成功!" << endl; 输出结果: 解决方案: 控制台还原旧版即可,打开程序- ... 
- 详解Apache Dubbo的SPI实现机制
			一.SPI SPI全称为Service Provider Interface,对应中文为服务发现机制.SPI类似一种可插拔机制,首先需要定义一个接口或一个约定,然后不同的场景可以对其进行实现,调用方在 ... 
- 不使用synchronized和lock,如何实现一个线程安全的单例
			单例,大家肯定都不陌生,这是Java中很重要的一个设计模式.稍微了解一点单例的朋友也都知道实现单例是要考虑并发问题的,一般情况下,我们都会使用synchronized来保证线程安全. 那么,如果有这样 ... 
- 一次性讲清楚spring中bean的生命周期之一:getSingleton方法
			要想讲清楚spring中bean的生命周期,真的是不容易,以AnnotationConfigApplicationContext上下文为基础来讲解bean的生命周期,AnnotationConfigA ... 
