#649 (Div. 2)B. Most socially-distanced subsequence

題目描述

Given a permutation p of length n, find its subsequence s1, s2, …, sk of length at least 2 such that:
|s1−s2|+|s2−s3|+…+|sk−1−sk| is as big as possible over all subsequences of p with length at least 2.
Among all such subsequences, choose the one whose length, k, is as small as possible.
If multiple subsequences satisfy these conditions, you are allowed to find any of them.
A sequence a is a subsequence of an array b if a can be obtained from b by deleting some (possibly, zero or all) elements.
A permutation of length n is an array of length n in which every element from 1 to n occurs exactly once.

Input

The first line contains an integer t (1≤t≤2⋅104) — the number of test cases. The description of the test cases follows.
The first line of each test case contains an integer n (2≤n≤105) — the length of the permutation p.
The second line of each test case contains n integers p1, p2, …, pn (1≤pi≤n, pi are distinct) — the elements of the permutation p.
The sum of n across the test cases doesn’t exceed 105.

Output

For each test case, the first line should contain the length of the found subsequence, k. The second line should contain s1, s2, …, sk — its elements.
If multiple subsequences satisfy these conditions, you are allowed to find any of them.

Example

input
2
3
3 2 1
4
1 3 4 2
output
2
3 1
3
1 4 2

Note

In the first test case, there are 4 subsequences of length at least 2:
[3,2] which gives us |3−2|=1.
[3,1] which gives us |3−1|=2.
[2,1] which gives us |2−1|=1.
[3,2,1] which gives us |3−2|+|2−1|=2.
So the answer is either [3,1] or [3,2,1]. Since we want the subsequence to be as short as possible, the answer is [3,1].

題目分析

不難發現,當數組中存在連續的3個數且存在單調性時(如:123、321),我們可以刪除三個數中間的數,這樣得到的結果是一樣的。
如:
1 2 3–> |1-2|+|2-3|=2。
刪除中間數
1 3 --> |1-3|=2。
還有,如果兩個相鄰的數是相等的,則也可以刪除其中一個。
這樣,我們就可以找出a[]中所有的長度在3以上且具有單調性的子串,刪除中間的數,只保留兩頭的兩個數。最後剩下的數列即爲答案。
這道題的思路很簡單,我感覺這道題的難點其實是寫代碼。。。。

代碼如下
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#include <map>
#include <unordered_map>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#include <iomanip>
#define LL long long
using namespace std;
const int N=1e5+5;
int a[N];
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n;
		cin>>n;
		vector<int> ans; 	//用vector來儲存答案串
		for(int i=0;i<n;i++)
			cin>>a[i];
		
		ans.push_back(a[0]);	//先將最頭上的數放入(因爲a[]兩頭的兩個數是不可能被刪的)
		for(int i=1;i<n-1;i++)	//枚舉中間數
		{	//每次取出答案數組中最右邊的數與a[i]和a[i+1]進行比較
			if(ans.back()==a[i]) continue;	//如果有兩個相鄰數相等,則只保留一個(即答案中的那個)
			if(ans.back()<a[i]&&a[i]<=a[i+1]) continue;//判斷三個相鄰的數是否具有單調性
			if(ans.back()>a[i]&&a[i]>=a[i+1]) continue;//有則跳過中間那個
			ans.push_back(a[i]);	//如果上述條件均不滿足則將a[i]放入答案數組
		}
		ans.push_back(a[n-1]);	//最後再將最後一個數放入
		cout<<ans.size()<<endl;
		for(int it:ans) 
		cout<<it<<' ';
		cout<<endl;
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章