Codeforces Round #726 (Div. 2)

C

C. Challenging Cliffs
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are a game designer and want to make an obstacle course. The player will walk from left to right. You have n heights of mountains already selected and want to arrange them so that the absolute difference of the heights of the first and last mountains is as small as possible.

In addition, you want to make the game difficult, and since walking uphill or flat is harder than walking downhill, the difficulty of the level will be the number of mountains i (1≤i<n) such that hi≤hi+1 where hi is the height of the i-th mountain. You don't want to waste any of the mountains you modelled, so you have to use all of them.

From all the arrangements that minimize |h1−hn|, find one that is the most difficult. If there are multiple orders that satisfy these requirements, you may find any.

Input
The first line will contain a single integer t (1≤t≤100) — the number of test cases. Then t test cases follow.

The first line of each test case contains a single integer n (2≤n≤2⋅105) — the number of mountains.

The second line of each test case contains n integers h1,…,hn (1≤hi≤109), where hi is the height of the i-th mountain.

It is guaranteed that the sum of n over all test cases does not exceed 2⋅105.

Output
For each test case, output n integers — the given heights in an order that maximizes the difficulty score among all orders that minimize |h1−hn|.

If there are multiple orders that satisfy these requirements, you may output any.

Example
inputCopy
2
4
4 2 1 2
2
3 1
outputCopy
2 4 1 2 
1 3
Note
In the first test case:

The player begins at height 2, next going up to height 4 increasing the difficulty by 1. After that he will go down to height 1 and the difficulty doesn't change because he is going downhill. Finally the player will go up to height 2 and the difficulty will increase by 1. The absolute difference between the starting height and the end height is equal to 0 and it's minimal. The difficulty is maximal.

In the second test case:

The player begins at height 1, next going up to height 3 increasing the difficulty by 1. The absolute difference between the starting height and the end height is equal to 2 and it's minimal as they are the only heights. The difficulty is maximal.
题解:排序后有a[1],a[2],a[3],..,a[k],a[k+1],..,a[n],
若a[k],a[k+1]插值最小,则有a[k],a[k+2],a[k+3],..,a[1],a[2],...a[k-1],a[k+1]最小,另外,若仅有2个数,则对两数排序即可。
#include<bits/stdc++.h>
#define int long long

using namespace std;

inline int read()  {  
    int x=0,f=1;  
    char ch=getchar();  
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}  
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}  
    return x*f;  
}

const int maxn=2e5+10;
int T,n;
bool book[maxn];
vector<int>q;
vector<int>ans;

void solve(){
    n=read();
    vector<int>h;
    for(int i=0;i<n;++i){
        int x;x=read();
        h.push_back(x);
    }
    if(h.size()==2){
        sort(h.begin(),h.end());
        cout<<h[0]<<" "<<h[1]<<endl;
        puts("");
        return;
    }
    else{
        sort(h.begin(),h.end());
        int d=0x3f3f3f3f;
        int pos;
        for(int i=1;i<n;++i){
            if(d>h[i]-h[i-1]){
                d=h[i]-h[i-1];
                pos=i-1;
            }
        }
        vector<int>ans;
        ans.push_back(h[pos]);
        for(int i=pos+2;i<n;++i)
            ans.push_back(h[i]);
        for(int i=0;i<pos;++i)
            ans.push_back(h[i]);
        ans.push_back(h[pos+1]);
        for(int i=0;i<ans.size();++i) cout<<ans[i]<<" ";
        puts("");
        return;
    }
}

signed main()
{
    T=read();
    while(T--) solve();
    //for(;;);
	return 0;
}

E1

E1. Erase and Extend (Easy Version)
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
This is the easy version of the problem. The only difference is the constraints on n and k. You can make hacks only if all versions of the problem are solved.

You have a string s, and you can do two types of operations on it:

Delete the last character of the string.
Duplicate the string: s:=s+s, where + denotes concatenation.
You can use each operation any number of times (possibly none).

Your task is to find the lexicographically smallest string of length exactly k that can be obtained by doing these operations on string s.

A string a is lexicographically smaller than a string b if and only if one of the following holds:

a is a prefix of b, but a≠b;
In the first position where a and b differ, the string a has a letter that appears earlier in the alphabet than the corresponding letter in b.
Input
The first line contains two integers n, k (1≤n,k≤5000) — the length of the original string s and the length of the desired string.

The second line contains the string s, consisting of n lowercase English letters.

Output
Print the lexicographically smallest string of length k that can be obtained by doing the operations on string s.

Examples
inputCopy
8 16
dbcadabc
outputCopy
dbcadabcdbcadabc
inputCopy
4 5
abcd
outputCopy
aaaaa
Note
In the first test, it is optimal to make one duplication: "dbcadabc" → "dbcadabcdbcadabc".

In the second test it is optimal to delete the last 3 characters, then duplicate the string 3 times, then delete the last 3 characters to make the string have length k.

"abcd" → "abc" → "ab" → "a" → "aa" → "aaaa" → "aaaaaaaa" → "aaaaaaa" → "aaaaaa" → "aaaaa".
题解:每次找到当前字典序最小的字符串即可,注意当找到>s[0]的就break,因为若从该项开始复制前面字串字典序一定比它小。
#include<bits/stdc++.h>
#define int long long

using namespace std;

inline int read()  {  
    int x=0,f=1;  
    char ch=getchar();  
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}  
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}  
    return x*f;  
}

const int maxn=10100;
int T,n,k;
vector<string>dp(maxn);

string get(string s,int k){
    while(s.size()<k) s+=s;
    while(s.size()>k) s.pop_back();
    return s;
}

void solve(){
    n=read(),k=read();
    string s;
    cin>>s;
    string ss="";
    ss+=s[0];
    string minn=get(ss,k);
    for(int i=1;i<n;++i){
        if(s[i]>s[0]) break;
        ss+=s[i];
        minn=min(minn,get(ss,k));
    }
    cout<<minn<<endl;
}

signed main()
{
    //cin>>T;
    //while(T--) solve();
    solve();
    //for(;;);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值