zoukankan      html  css  js  c++  java
  • Codeforces 1385C

    C. Make It Good

    time limit per test1 second
    memory limit per test256 megabytes
    input standard input
    output standard output
    You are given an array a consisting of n integers. You have to find the length of the smallest (shortest) prefix of elements you need to erase from a to make it a good array. Recall that the prefix of the array a=[a1,a2,…,an] is a subarray consisting several first elements: the prefix of the array a of length k is the array [a1,a2,…,ak] (0≤k≤n).

    The array b of length m is called good, if you can obtain a non-decreasing array c (c1≤c2≤⋯≤cm) from it, repeating the following operation m times (initially, c is empty):

    select either the first or the last element of b, remove it from b, and append it to the end of the array c.
    For example, if we do 4 operations: take b1, then bm, then bm−1 and at last b2, then b becomes [b3,b4,…,bm−3] and c=[b1,bm,bm−1,b2].

    Consider the following example: b=[1,2,3,4,4,2,1]. This array is good because we can obtain non-decreasing array c from it by the following sequence of operations:

    take the first element of b, so b=[2,3,4,4,2,1], c=[1];
    take the last element of b, so b=[2,3,4,4,2], c=[1,1];
    take the last element of b, so b=[2,3,4,4], c=[1,1,2];
    take the first element of b, so b=[3,4,4], c=[1,1,2,2];
    take the first element of b, so b=[4,4], c=[1,1,2,2,3];
    take the last element of b, so b=[4], c=[1,1,2,2,3,4];
    take the only element of b, so b=[], c=[1,1,2,2,3,4,4] — c is non-decreasing.
    Note that the array consisting of one element is good.

    Print the length of the shortest prefix of a to delete (erase), to make a to be a good array. Note that the required length can be 0.

    You have to answer t independent test cases.

    Input

    The first line of the input contains one integer t (1≤t≤2⋅104) — the number of test cases. Then t test cases follow.

    The first line of the test case contains one integer n (1≤n≤2⋅105) — the length of a. The second line of the test case contains n integers a1,a2,…,an (1≤ai≤2⋅105), where ai is the i-th element of a.

    It is guaranteed that the sum of n does not exceed 2⋅105 (∑n≤2⋅105).

    Output

    For each test case, print the answer: the length of the shortest prefix of elements you need to erase from a to make it a good array.

    Example
    input
    5
    4
    1 2 3 4
    7
    4 3 3 8 4 5 2
    3
    1 1 1
    7
    1 3 1 4 5 3 2
    5
    5 4 3 2 3
    outputCopy
    0
    4
    0
    2
    3

    Note

    In the first test case of the example, the array a is already good, so we don’t need to erase any prefix.

    In the second test case of the example, the initial array a is not good. Let’s erase first 4 elements of a, the result is [4,5,2]. The resulting array is good. You can prove that if you erase fewer number of first elements, the result will not be good.

    题目大意:

    给出 t 组测试样例,每组输入一个长度为 n 的数组,需要这个数组的一定长度的前缀使得剩余数组只从前后取数,能形成一个有序的序列。求删除的最小长度。

    解题思路:

    这道题我是分了3种情况的。

    • 如果给出的数组不递增,则ans = 0
    • 如果给出的数组不递减 ,则ans = 0
    • 正常情况 有增有减

    对于前两种情况遍历一下即可,对于第三种情况,可以倒着找,找最后一个过山车数组(中间高两边低),用总长度减去过山车数组的长度即可。AC代码:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <map>
    #include <set>
    #include <vector>
    using namespace std;
    const int N = 2e5 + 50;
    typedef long long ll;
    vector<int> v;
    int main()
    {
    	int t;
    	cin >> t;
    	while (t--)
    	{
    		v.clear();
    		int n;
    		cin >> n;
    		for (int i = 0; i < n; i++)
    		{
    			int s;
    			cin >> s;
    			v.push_back(s);
    		}
    		int ans1 = 1, ans2 = 1, ans3 = 1;
    		for (int i = n - 2; i >= 0 ; i --)
    		{
    			if (v[i] >= v[i + 1])
    			  ans1++;
    			else
    			  break;
    		}
    		for (int i = n - 2; i >= 0 ; i --)
    		{
    			if (v[i] <= v[i + 1])
    			  ans2++;
    			else
    			  break;
    		}
    		if (ans1 == v.size() || ans2 == v.size())//两种特殊情况
    		{
    			cout << 0 << endl;
    			continue;
    		}
    		bool flag = true;
    		for (int i = n - 2; i >= 0; i --)//倒着找
    		{
    			if (flag)
    			{
    				if (v[i] >= v[i + 1])
    				  ans3++;
    				else
    				{
    					ans3++;
    					flag = false;
    				}
    			}
    			else
    			{
    				if (v[i] <= v[i + 1])
    				  ans3++;
    				else
    				  break;
    			}
    		}
    		int len = max(ans1, max(ans2, ans3));
    		len = v.size() - len;
    		cout << len << endl;
    	}
    	return 0;
    }
    

    优化:

    对于这种写法显然太麻烦了,可以把三种情况结合一下,直接倒着找,先找从后往前第一个连续不降的序列,存一下位置,再接着这个位置找一下不增的序列,最后直接输出存的位置即可。标程:

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <map>
    #include <set>
    using namespace std;
    int main()
    {
    	int t;
    	cin >> t;
    	while (t--)
    	{
    		int n;
    		cin >> n;
    		vector<int > v;
    		for (int i = 1; i <= n; i ++)
    		{
    			int s;
    			cin >> s;
    			v.push_back(s);
    		}
    		int pos = n - 1;
    		while (pos > 0 && v[pos - 1] >= v[pos])  pos--;//先找不降的
    		while (pos > 0 && v[pos - 1] <= v[pos])  pos--;//再找不增的
    		cout << pos << endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    Python数据结构之字符串
    Python中的logging模块
    Python资源大全中文版
    test
    Python数据结构之元组
    Python之StringIO和BytesIO
    Python标准库之pathlib
    Ubuntu下安装pyenv管理多版本python
    生成器 Generator
    CIDR网段格式
  • 原文地址:https://www.cnblogs.com/Hayasaka/p/14294200.html
Copyright © 2011-2022 走看看