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();
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章