2021-02-20周赛


前言

2-20周赛


一、Make It Good

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
Output
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.

题意就是从一个数列的前面或者是后面依次选一个数放着,使得新的数列单调不递减。
思路由于要删的前缀最短,也就是要留下来的后缀最长,也就是找过山车序列。
首先我们可以发现若一个序列是好序列,那么整个序列肯定形似一个山峰,且只有一个峰且
是高峰(高峰连续相等也算)。而现在我们只能删除前缀,所以我们肯定要保留最右的高峰。所以思路如下:我们首先从右向左找到第一个高峰,如果再往前找到一个低峰则低峰前的元素全要删除,倘若找不到,那自然一个元素也不用删除,代表此序列已经是一个好序列。
在这里插入图片描述

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<cstdio>
#include<queue>
#include<cmath>

using namespace std;

int a[200000+5];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
    int n;
   scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    int flag=1,cnt=0;
    for(int i=n;i>0;i--)
    {
        if(a[i-1]<a[i])cnt=1;//寻找低峰
        else if(cnt&&a[i-1]>a[i])
        {
                printf("%d\n",i-1);
                flag=0;
                break;
        }

    }
    if(flag)
       printf("0\n");
}
  return 0;
}

由于数组开小了一个0 ,还有用了cin和cout就超时了。

二、Choosing flowers

Vladimir would like to prepare a present for his wife: they have an anniversary! He decided to buy her exactly n flowers.

Vladimir went to a flower shop, and he was amazed to see that there are m types of flowers being sold there, and there is unlimited supply of flowers of each type. Vladimir wants to choose flowers to maximize the happiness of his wife. He knows that after receiving the first flower of the i-th type happiness of his wife increases by ai and after receiving each consecutive flower of this type her happiness increases by bi. That is, if among the chosen flowers there are xi>0 flowers of type i, his wife gets ai+(xi−1)⋅bi additional happiness (and if there are no flowers of type i, she gets nothing for this particular type).

Please help Vladimir to choose exactly n flowers to maximize the total happiness of his wife.

Input
The first line contains the only integer t (1≤t≤10000), the number of test cases. It is followed by t descriptions of the test cases.

Each test case description starts with two integers n and m (1≤n≤109, 1≤m≤100000), the number of flowers Vladimir needs to choose and the number of types of available flowers.

The following m lines describe the types of flowers: each line contains integers ai and bi (0≤ai,bi≤109) for i-th available type of flowers.

The test cases are separated by a blank line. It is guaranteed that the sum of values m among all test cases does not exceed 100000.

Output
For each test case output a single integer: the maximum total happiness of Vladimir’s wife after choosing exactly n flowers optimally.

Example
Input
2
4 3
5 0
1 4
2 2

5 3
5 2
4 2
3 1
Output
14
16
Note
In the first example case Vladimir can pick 1 flower of the first type and 3 flowers of the second type, in this case the total happiness equals 5+(1+2⋅4)=14.

In the second example Vladimir can pick 2 flowers of the first type, 2 flowers of the second type, and 1 flower of the third type, in this case the total happiness equals (5+1⋅2)+(4+1⋅2)+3=16.

方法一:

前提知识:前缀和,二分
购买k次以上(k>1)的花只会买一种(当然也有可能0种,后面再考虑一下即可)。那么只需要找到是哪种花购买1次以上,对于购买了k次的花记为x,则我们会发现如果少购买一次bx,去购买一个ai(ai>bx)则会使得总数值更高,因此对于每种bx,我们在购买它之前需要把所有ai>bx的花都先买下来。因此可以先按照ai进行排序,然后记录下ai的前缀和sum[i],之后枚举每一个bi,二分查找到最大的p使得ap>bi(即为最小的ap使得ap>bi),剩下的花就全部购买bi。
处理过程需要注意:
如果p>=n,则最多只能购买sum[n]而不是sum[p]
如果i>p,则说明当前bi对应的第一次购买ai还没有被购买,需要先购买一次ai,剩下的n-p-1次才能购买bi。
如果i<=p,剩下的n-p次全部购买bi。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<cstdio>
#include<queue>
#include<cmath>

using namespace std;

#define PLL pair<long long ,long long>
PLLa[100005];
long long  sum[100005];

int f(int l,int r,long long num)//二分查找
{
    int ans=-1;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(a[mid].first>mid)
        {
            ans=mid;
            l=mid+1;
        }
        else r=mid-1;
    }
    return ans;    
}

int main()
{
int t;
scanf("%d",&t);
while(t--)
{
    int n,m;
   scanf(" %d %d",&n,&m);
   int i;
    for(i=1;i<=n;i++)
       {
            scanf("%d %d",&a[i].first,&a[i].second);
            sum[i]=0;
       }
       sort(x+1, x+m+1, greater<PLL>());
         for(i=1;i<=n;i++)
       {
            if(i!=1)
            sum[i]=sum[i-1]+a[i].first;
            else sum[i]=a[i].first;
       }
    long long ans=0;
    for(i=0;i<m;i++)
    {
        int p=upper(1,m,x[i].second);
        if(p!=-1)
        {
           ans = max(ans, sum[min(p, n-1)] + (p < i ? max(0, n - p - 2) * x[i].second + (n>p+1?x[i].first:0) : max(0, n - p-1) * x[i].second));
        }
        else 
            ans=max(ans,(n-1)*x[i].second+x[i].first);
    }    long long ans2=0;
    for(i=0;i<m&&n;i++)
    {
        ans2+=x[i].first;
        n--;
    }
    cout<<max(ans2,ans)<<endl;
}
    
  return 0;
}

方法二:

在这里插入图片描述

#include <iostream> 
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1e5 + 5;
typedef long long ll;
ll n, m;
ll a[N], a_[N];
ll b[N];
ll sum[N];
ll Max;
int main()
{
#ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); 
    freopen("out.txt", "w", stdout);
#endifint T; 
    scanf("%d", &T);
    while(T--)
    {
        Max = 0ll;
        scanf("%lld%lld", &n, &m);
        for (int i = 1; i <= m; ++i) scanf("%lld%lld", &a[i], &b[i]), a_[i] = a[i];
        sort(a + 1, a + m + 1), a[m + 1] = 1e9 + 1;
        for (int i = 1; i <= m; ++i) sum[i] = sum[i - 1] + a[i];
        for (int i = 1; i <= m; ++i)
        {
            int pos = upper_bound(a + 1, a + 1 + m, b[i]) - a;
            if (m - pos + 1 >= n) Max = max(Max, sum[m] - sum[m - n]);
            else
            {
                if (a_[i] >= a[pos]) Max = max(Max, sum[m] - sum[pos - 1] + (n - (m - pos + 1)) * b[i]);
                else
                {
                    ll temp1 = 0;
                    ll temp2 = 0;
                    ll sheng = max(0ll, n - (m - pos + 2));
                    temp1 = sum[m] - sum[pos - 1] + a_[i] + sheng * b[i];
                    if (m >= n) temp2 = sum[m] - sum[m - n];
                    ll Max_temp = max(temp1, temp2);
                    Max = max(Max, Max_temp);
                }
            }
        }
        printf("%lld\n", Max);
    }
}

greater()的用法

#include//因为用了greater()

sort(a,a+len,greater());//内置类型的由大到小排序

greater对应的是less

三、Replace by MEX

在这里插入图片描述

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
const int N = 1e3 + 3;
vector<int> op;
int n;
int vis[N];
int a[N];
int find_MEX()
{
    memset(vis, 0, sizeof vis);
    for (int i = 0; i < n; ++i) vis[a[i]] = 1;
    for (int i = 0; i <= n; ++i)
    {
        if (!vis[i]) return i;
    }
    return -1;
}
int main()
{
#ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); 
    freopen("out.txt", "w", stdout);
#endifint T; 
    scanf("%d", &T);
    while(T--)
    {
        op.clear();
        scanf("%d", &n);
        for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
        while(1)
        {
            int MEX = find_MEX();
            if (MEX == n)
            {
                int temp = -1;
                for (int i = 0; i < n; ++i)
                {
                    if (a[i] != i)
                    {
                        temp = i;
                        a[i] = n;
                        break;
                    }
                }
                if (temp == -1) break;
                else op.push_back(temp + 1);
            }
            else
            {
                a[MEX] = MEX;
                op.push_back(MEX + 1);
            }
        }
        printf("%d\n", (int)op.size());
        for (int i = 0; i < op.size(); ++i) printf("%d ", op[i]);
        putchar('\n');
    }
}

四、输入存在空格时

cin和scanf在遇到空格、回车、换行符都会结束

string类型读取字符串string s; getline(cin,s)
char[]类型读取字符串char s[n];cin.getline(s,n);

五、语法错误( error: array bound is not an integer constant before ‘]’ token)

这个就是在定义MAX的时候没有加const,加了const之后才可以放在数组中。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值