Codeforces Round #631(div.2) A~B

A:Dreamoon and Ranking Collection

题目描述:

The sequence of mm integers is called the permutation if it contains all integers from 11 to mm exactly once. The number mm is called the length of the permutation.

Dreamoon has two permutations p1p1 and p2p2 of non-zero lengths l1l1 and l2l2.

Now Dreamoon concatenates these two permutations into another sequence aa of length l1+l2l1+l2. First l1l1 elements of aa is the permutation p1p1 and next l2l2 elements of aa is the permutation p2p2.

You are given the sequence aa, and you need to find two permutations p1p1 and p2p2. If there are several possible ways to restore them, you should find all of them. (Note that it is also possible that there will be no ways.)

Input:

The first line contains an integer tt (1≤t≤51≤t≤5) denoting the number of test cases in the input.

Each test case contains two lines. The first line contains two integers n,xn,x (1≤n,x≤1001≤n,x≤100). The second line contains nn positive non-zero integers a1,a2,…,ana1,a2,…,an (1≤ai≤1001≤ai≤100).

Output

Output:

For each test case print one line containing the largest vv, such that it is possible that after xx other contests, for each 1≤i≤v1≤i≤v, there will exist a contest where this person took the ii-th place.

Sample Input:

5
6 2
3 1 1 5 7 10
1 100
100
11 1
1 1 1 1 1 1 1 1 1 1 1
1 1
1
4 57
80 60 40 20

Sample Output:

5
101
2
2
60

Hint:

The first test case is described in the statement.

In the second test case, the person has one hundred future contests, so he can take place 1,2,…,991,2,…,99 and place 101101 on them in some order, to collect places 1,2,…,1011,2,…,101.

题目大意:

这道题题目挺难看懂的,就是给出了一个长度为n的数组(当前这个人要参加为n场的比赛),然后给出了x(x场将要参加的比赛),在这为n的数组中,每一个数字代表了他在比赛中占领的位置,他要求占领的位置从1连续,并且输出最大占领位置,例如:第一个样例子中,3 1 1 5 7 10,占领了1 3 5 7 10的位置,输入了是x,那么未来有x场比赛,最多占领2个,那么可以看到1到5中缺2和4,那么未来x场比赛只要占领2和4就能形成1~5的连续位置。

思路分析:

这道题我们从x场比赛来看,那么如果有x场比赛,说明可以占x个位置,但n个比赛的位置在x的范围内时,x就要自增一下,因为你不可能n已经占领了,你还要占领,那么就可以继续占领x数字后的位置,
那么举个例子:最后一个样例中,40和20在x(57)的范围内,那么从1~57就已经有了40 20这2个位置,那么我们x就多了2个占领位置,那么自增到59,到59了因为59和60差一位,继续自增,连起来连续,当没有比他小并且不与他差1时,说明已经达到了最大位置了,可以输出。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<set>
using namespace std;
int main()
{
	int t;
	int n,m;
	cin >> t;
	while(t--)
	{
		set<int>q;
		int x;
		cin >> n >> m;
		for(int i=1;i<=n;i++)
		{
			cin >> x;
			q.insert(x);
		}
		set<int>::iterator it;
		for(it=q.begin();it!=q.end();it++)
		{
			if(*it<=m || *it==m+1)
			{
				m++;
			}
		}
		cout << m << endl;
	}
}

B:Dreamoon Likes Permutations

题目描述:

The sequence of mm integers is called the permutation if it contains all integers from 11 to mm exactly once. The number mm is called the length of the permutation.

Dreamoon has two permutations p1p1 and p2p2 of non-zero lengths l1l1 and l2l2.

Now Dreamoon concatenates these two permutations into another sequence aa of length l1+l2l1+l2. First l1l1 elements of aa is the permutation p1p1 and next l2l2 elements of aa is the permutation p2p2.

You are given the sequence aa, and you need to find two permutations p1p1 and p2p2. If there are several possible ways to restore them, you should find all of them. (Note that it is also possible that there will be no ways.)

Input:

The first line contains an integer tt (1≤t≤100001≤t≤10000) denoting the number of test cases in the input.

Each test case contains two lines. The first line contains one integer nn (2≤n≤2000002≤n≤200000): the length of aa. The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤n−11≤ai≤n−1).

The total sum of nn is less than 200000200000.

Output:

For each test case, the first line of output should contain one integer kk: the number of ways to divide aa into permutations p1p1 and p2p2.

Each of the next kk lines should contain two integers l1l1 and l2l2 (1≤l1,l2≤n,l1+l2=n1≤l1,l2≤n,l1+l2=n), denoting, that it is possible to divide aa into two permutations of length l1l1 and l2l2 (p1p1 is the first l1l1 elements of aa, and p2p2 is the last l2l2 elements of aa). You can print solutions in any order.

Sample Input:

6
5
1 4 3 2 1
6
2 4 1 3 2 1
4
2 1 1 3
4
1 3 3 1
12
2 1 3 4 5 6 7 8 9 1 10 2
3
1 1 1

Sample Output:

2
1 4
4 1
1
4 2
0
0
1
2 10
0

Hint:

In the first example, two possible ways to divide aa into permutations are {1}+{4,3,2,1}{1}+{4,3,2,1} and {1,4,3,2}+{1}{1,4,3,2}+{1}.

In the second example, the only way to divide aa into permutations is {2,4,1,3}+{2,1}{2,4,1,3}+{2,1}.

In the third example, there are no possible ways.

题目大意:

这道题也有点难懂(对于自己),就是给了一个n长的数组,这个数组是由2个部分组成,分别是长度为L1的p1数组,以及长度为L2的L2数组,并且L1+L2=n,并且p1与p2是连续的(就是从1连续),那么题目要求我们还原n的2个部分的可能长度L1和L2.(题目存在无法还原现象)。

思路分析:

这道题其实有几个特殊条件,当1出现的次数小于2的时候,说明可以直接输出0了,或者当一个元素出现次数大于2的时候,也输出0,因为他是分成2个部分的,如果要保持连续并且2部分,首先1要出现2次,或者其他元素出现的次数必须<=2,当排除这些条件的时候,我们可以先用一个Set来存放所有元素,另一个Set来接收,不断释放与接受,用Map来记元素出现的次数,详细看代码解析.

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<set>
#include<vector>
#include<map> 
using namespace std;
void LemonSolve()
{
	int flag=0;
	int n;
	int a[200000];
	cin >> n;
	set<int>s1,s2;
	vector<pair<int,int> >q;
	map<int,int>m;
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
		s1.insert(a[i]);
		m[a[i]]++;
		if(m[a[i]]>=3)flag=1;
	}
	if(m[1]<2 || flag)
	{
	printf("0\n");
	return;
}
for(int i=0;i<n;i++)
{
	if(m[a[i]]==2)
	{
	s2.insert(a[i]);
	m[a[i]]--;
	continue;
}
if(s2.size())
{
	int m1=*(s1.rbegin());
	int m2=*(s2.rbegin());  
	if(m1==s1.size() && m2==s2.size() && m2==i && m1==n-i)
	{
		q.push_back(make_pair(i,n-i));
	}
}
if(m[a[i]]==1)
{
	s2.insert(a[i]);
	s1.erase(a[i]);
}	
}
		cout << q.size() << endl;
		for(auto i:q)
		{
			cout << i.first << " " << i.second << "\n";
		}
}
int main()
{
	int t;
	cin >> t;
	while(t--)
	{
		LemonSolve();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值