Codeforces Round #723 (Div. 2)

Codeforces Round #723 (Div. 2)

A. Mean Inequality

在这里插入图片描述

Example

input

3
3
1 2 3 4 5 6
2
123 456 789 10
1
6 9

output

3 1 4 2 5 6
123 10 456 789
9 6

在这里插入图片描述

题目大意:

给一个2 n长的元素不重复的数组,任意交换位置,使得任一元素的左右两元素之和不等于本身的两倍,求这个新的数组。

思路:

先从简单的看起,假设a<b<c 或c<b<a, a+c=2 b,那么a,b,c就构成一个等差数列,我们的目的是让它不是等差数列,只要构造成b,a,c 或a,c,b就行了,即 高低高,低高低。

代码:

#include<algorithm>
#include<iostream>
#include<cmath>
#define int long long
using namespace std;

int a[100];

signed main()
{
    
    
    int t;
    cin>>t;
    while(t--)
    {
    
    
        int n;
        cin>>n;
        n*=2;
        for(int i=0;i<n;++i)
        {
    
    
            cin>>a[i];
        }
        sort(a,a+n);
        for(int i=0;i<n/2;++i)
        {
    
    
            cout<<a[i]<<' ';
            cout<<a[n-i-1]<<' ';
        }
        cout<<endl;
    }
	return 0;
}


B. I Hate 1111

在这里插入图片描述

Example

input

3
33
144
69

output

YES
YES
NO

题目大意:

给你一个数,问你这个数能不能用任意个11,111,1111…相加得来。

思路:

数论,任意互质的正整数a,b,a* n+b* m所表示不出来的最大数是a* b-a-b.

因为11与111互质,所以11* 111-11-111=1099,即只要用这两个数字,就可以表示出>1099的数字,那么1-1099可以直接暴力求出来是否可以用11和111表示.

代码:

#include<algorithm>
#include<iostream>
#include<cmath>
#include<map>
#define int long long
using namespace std;

map<int,bool>ma;

signed main()
{
    
    
    int t;
    for(int i=0;i<=1100;i+=11)
    {
    
    
        for(int j=0;j<=1100;j+=111)
        {
    
    
            if(i+j<=1100)
            {
    
    
                ma[i+j]=1;//求1-1099可以被11和111表示出来的数字
            }
        }
    }
    cin>>t;
    while(t--)
    {
    
    
        int n;
        cin>>n;
        if(n>1099||ma[n])cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
	return 0;
}

简化版本:

signed main()
{
    
    
    int t;
    cin>>t;
    while(t--)
    {
    
    
        int n;
        cin>>n;
        if(n/110>=n%11)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
	return 0;
}

C. Potions

在这里插入图片描述

Example

input

6
4 -4 1 -3 1 -3

output

5

题目大意:

给一个数组,初始时你血量为0,元素从左到右,可以选择加上或者不加上,要求每时每刻血量不为负数,求最终最大的元素个数。

思路:

优先队列,从左到右,每个值都先吃进去,同时把负值塞入小顶堆优先队列,如果血量变成负数,就把之前吃进去的最小值吐出来,ans-1,每吃一个就求一次最大长度。

两题都可以这样做…好水啊。而且白书上面有原题…

代码:

#include<algorithm>
#include<iostream>
#include<cmath>
#define int long long
using namespace std;

priority_queue<int,vector<int>,greater<int>>p;

signed main()
{
    
    
    int n;
    cin>>n;
    int h=0;
    int ans=0;
    int temp=0;
    for(int i=0;i<n;++i)
    {
    
    
        int a;
        cin>>a;
        if(a<0)
        {
    
    
            p.push(a);
        }
        h+=a;
        ++temp;
        if(h<0)
        {
    
    
            --temp;
            h-=p.top();
            p.pop();
        }
        ans=max(ans,temp);
    }
    cout<<ans<<endl;
	return 0;
}

D. Kill Anton

在这里插入图片描述
Example
input

4
ANTON
NAAN
AAAAAA
OAANTTON

output

NNOTA
AANN
AAAAAA
TNNTAOOA

在这里插入图片描述

题目大意:

给一个只有 A N T O 的字符串,可以交换相邻的字符,求最大还原步数的改变后的字符串。

思路:

暴力枚举每个字符串的全排列,记录最大的逆序对数,那个字符串就是花最多步数的答案。

cf大佬的代码:

#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define int int64_t
typedef tree<pair<int,char>, null_type, less<pair<int,char>>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
string s;

int check(string s1)
{
    
    
	ordered_set os;
	int ans=0;
	deque<int>store[4];
	for(int i=0;i<s1.size();i++)
    {
    
    
		os.insert({
    
    i,s1[i]});
		if (s1[i]=='A'){
    
    store[0].push_back(i);}
		else if (s1[i]=='N'){
    
    store[1].push_back(i);}
		else if (s1[i]=='O'){
    
    store[2].push_back(i);}
		else{
    
    store[3].push_back(i);}
	}
	for(int i=0;i<s.size()-1;i++)
    {
    
    
		int x=0;
		if(s[i]=='N'){
    
    x=1;}
		else if(s[i]=='O'){
    
    x=2;}
		else if(s[i]!='A'){
    
    x=3;}
		int y=x;
		x=store[x].front();
		store[y].pop_front();
		ans+=os.order_of_key({
    
    x,s[i]});
		auto it=os.find({
    
    x,s[i]});
		os.erase(it);
	}
	return ans;
}

signed main()
{
    
    
    int t;
    cin>>t;
    while(t--)
    {
    
    
        cin>>s;
        string s1,s2,s3,s4;
        for(auto it:s)
        {
    
    
            if(it=='A'){
    
    s1+=it;}
            else if(it=='N'){
    
    s2+=it;}
            else if(it=='O'){
    
    s3+=it;}
            else{
    
    s4+=it;}
        }
        vector<string>z{
    
    s1,s2,s3,s4};
        string ans;
        int ma=-1;
        do
        {
    
    
            string gh;
            for(string it:z){
    
    gh+=it;}//以字典序最小的样子开始
            int pres=check(gh);
            if(pres>ma)
            {
    
    
                ma=pres;
                ans=gh;
            }
        }while(next_permutation(z.begin(),z.end()));
        cout<<ans<<endl;
    }
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Story_1419/article/details/117387362