Codeforces Round 874 (Div. 3)

Codeforces Round 874

A.Musical Puzzle

在这里插入图片描述
Example
input

5
4
abab
7
abacaba
6
aaaaaa
7
abcdefg
5
babdd

output

2
4
1
6
4

Note

In the first sample, you need to record the melodies “ab” and “ba”, as
described in the problem statement.

In the second sample, you need to record the melodies “ab”, “ba”,
“ac”, and “ca”.

In the third sample, the only necessary melody is “aa”.

题意:

给出一个字符串,只包含字符a,b,c,d,e,f,g
由于题目要求,长的字符串只能拼接而成,每次拼接字符串长度不能大于2
而且必须一个字符串的最后一个字符和另一个字符串的第一个字符相等才能拼接,问给出的字符串需要多少种短字符串才能拼接而成

题解:

遍历字符串,每次截取两个长度,判断是否记录过,如果没记录过总和加一即可
下面是用map的,其实慢了

#include <bits/stdc++.h>
using namespace std;

#define x first
#define y second
#define lowbit(x) ((x)&(-(x)))
#define int long long
#define rep(i,a,b) for(int i=(int)a,i##i=(int)b;i<=i##i;i++)
#define per(i,a,b) for(int i=(int)a,i##i=(int)b;i>=i##i;i--)
typedef long long ll;
typedef pair<int,int> PII;
typedef unsigned long long ULL;
const int N = 1000005;
const double PI = acos(-1);


void solve()
{
    map<string,bool>yes;
    int n;cin>>n;
    string s;
    cin>>s;
    int ans=0;
    for(int i=0;i<s.size()-1;i++){
        string ss;
        ss=s.substr(i,2);
        if(!yes[ss]){
            yes[ss]=true;
            ans++;
        }
    }
    cout<<ans<<'\n';
}

signed main()
{
    std::ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int _ = 1;
    cin>>_;
    while(_--)
        solve();
}

题解2:

用set直接自动去重
快的鸭皮

#include <iostream>
#include <set>
using namespace std;
void solve(){
    set<string>se;
    int num;cin>>num;
    string s;cin>>s;
    for(int i=0;i<s.size()-1;i++)se.insert(s.substr(i,2));
    cout<<se.size()<<endl;
}
int main(){
    int _=1;cin>>_;
    while(_--)solve();
    return 0;
}

B.Restore the Weather

在这里插入图片描述

题目大意:

给出一个长度为 n n n的数组a和数组b,数组b是混乱的。给出 k k k
但数组a的每一个数,在数组b中都有对应的数,对应规则: ∣ a i − b j ∣ < k |a_i-b_j|<k aibj<k
现在让你输出对的数组b(和对应下标的数组a中每一个数都满足上述规则)

题解:

把a和b都排序,小对小,大对大,肯定满足规则,然后再按照原来的下标排序然后打印即可

#include <bits/stdc++.h>
using namespace std;

#define x first
#define y second
#define lowbit(x) ((x)&(-(x)))
#define int long long
#define rep(i,a,b) for(int i=(int)a,i##i=(int)b;i<=i##i;i++)
#define per(i,a,b) for(int i=(int)a,i##i=(int)b;i>=i##i;i--)
typedef long long ll;
typedef pair<int,int> PII;
typedef unsigned long long ULL;
const int N = 1000005;
const double PI = acos(-1);

struct node{
    int x,i;
    int b;
};
inline bool cmp(node a,node b){
    return a.x<b.x;
}
inline bool cmp2(node a,node b){
    return a.i<b.i;
}
void solve()
{

    int n,k;cin>>n>>k;
    node a[n+1];
    int b[n+1];
    for(int i=1;i<=n;i++) { cin >> a[i].x;a[i].i=i; }
    for(int i=1;i<=n;i++)cin>>b[i];
    sort(a+1,a+n+1,cmp);
    sort(b+1,b+n+1);
    for(int i=1;i<=n;i++)a[i].b=b[i];
    sort(a+1,a+n+1,cmp2);
    for(int i=1;i<=n;i++)cout<<a[i].b<<' ';
    cout<<'\n';
}

signed main()
{
    std::ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int _ = 1;
    cin>>_;
    while(_--)
        solve();
}

C. Vlad Building Beautiful Array

在这里插入图片描述
Example
input

7
5
2 6 8 4 3
5
1 4 7 6 9
4
2 6 4 10
7
5 29 13 9 10000001 11 3
5
2 1 2 4 2
5
2 4 5 4 3
4
2 5 5 4

output

NO
YES
YES
YES
YES
NO
NO

题意:

给出长度为 n n n的数组a,在数组a里面按照两者方式选择,组成数组b,要求数组b的数都大于0,并且里面的数奇偶性相同
方式1:选择 a i a_i ai
方式2:选择 a i − a j ( 1 ≤ j ≤ n ) a_i-a_j (1\leq j\leq n) aiaj(1jn)
如果可以组成满足规则的数组b就输出"YES"
否则"NO"

题解:

通过偶-偶=偶,偶-奇=奇,寄-寄=偶,寄-偶=寄
如果数组a出现了奇数,那么数组b的数一定得是奇数,因为无论怎么变化,最小的奇数始终无法变为偶数
还有一点,如果有出现偶数小于最小的奇数的情况,那么该偶数就无法通过减法变成大于0的奇数,也就是说该偶数到数组b里面还是偶数。
所以我只需要判断有没有奇数,如果没有,那么表明数组a全偶,直接选到数组b即可,输出"YES"
如果有奇数,就要记录并判断最小奇数和最小偶数的关系,如果最小偶数小于奇数,那么就是无法变为全奇的情况,这也是唯一"NO"的情况

#include <bits/stdc++.h>
using namespace std;

#define x first
#define y second
#define lowbit(x) ((x)&(-(x)))
#define int long long
#define rep(i,a,b) for(int i=(int)a,i##i=(int)b;i<=i##i;i++)
#define per(i,a,b) for(int i=(int)a,i##i=(int)b;i>=i##i;i--)
typedef long long ll;
typedef pair<int,int> PII;
typedef unsigned long long ULL;
const int N = 1000005;
const double PI = acos(-1);


void solve()
{
    int n;
    cin>>n;
    int flag=0;
    int min_ji=INT_MAX;
    int min_ou=INT_MAX;
    int a[n+1];
    for(int i=0;i<n;i++) { cin >> a[i];
        if(a[i]&1)
        {
            flag = 1;
            min_ji=min(min_ji,a[i]);
        }
        else min_ou=min(min_ou,a[i]);
    }
    if(flag){
        //quan ji
        if(min_ou>min_ji){cout<<"YES\n";}
        else cout<<"NO\n";
    }
    else
    cout<<"YES\n";
}

signed main()
{
    std::ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int _ = 1;
    cin>>_;
    while(_--)
        solve();
}

SSerxhs‘s code

//这回只花了114514min就打完了。
//真好。记得多手造几组。ACM拍什么拍。 
#include "bits/stdc++.h"
using namespace std;
template<typename T1,typename T2> istream &operator>>(istream &cin,pair<T1,T2> &a) { return cin>>a.first>>a.second; }
template<typename T1> istream &operator>>(istream &cin,vector<T1> &a) { for (auto &x:a) cin>>x; return cin; }
template<typename T1,typename T2> ostream &operator<<(ostream &cout,const pair<T1,T2> &a) { return cout<<a.first<<' '<<a.second; }
template<typename T1,typename T2> ostream &operator<<(ostream &cout,const vector<pair<T1,T2>> &a) { for (auto &x:a) cout<<x<<'\n'; return cout; }
template<typename T1> ostream &operator<<(ostream &cout,const vector<T1> &a) { int n=a.size(); if (!n) return cout; cout<<a[0]; for (int i=1; i<n; i++) cout<<' '<<a[i]; return cout; }
template<typename T1,typename T2> bool cmin(T1 &x,const T2 &y) { if (y<x) { x=y; return 1; } return 0; }
template<typename T1,typename T2> bool cmax(T1 &x,const T2 &y) { if (x<y) { x=y; return 1; } return 0; }
template<typename T1> vector<T1> range(T1 l,T1 r,T1 step=1) { assert(step>0); int n=(r-l+step-1)/step,i; vector<T1> res(n); for (i=0; i<n; i++) res[i]=l+step*i; return res; }
template<typename T1> basic_string<T1> operator*(const basic_string<T1> &s,int m) { auto r=s; m*=s.size(); r.resize(m); for (int i=s.size(); i<m; i++) r[i]=r[i-s.size()]; return r; }
#if !defined(ONLINE_JUDGE)&&defined(LOCAL)
#include "my_header\debug.h"
#else
#define dbg(...) ;
#define dbgn(...) ;
#endif
typedef unsigned int ui;
typedef long long ll;
#define all(x) (x).begin(),(x).end()
// template<typename T1,typename T2> void inc(T1 &x,const T2 &y) { if ((x+=y)>=p) x-=p; }
// template<typename T1,typename T2> void dec(T1 &x,const T2 &y) { if ((x+=p-y)>=p) x-=p; }
const int N=1e6+5;
int main()
{
	ios::sync_with_stdio(0); cin.tie(0);
	cout<<fixed<<setprecision(15);
	int T; cin>>T;
	while (T--)
	{
		int n,m,i,j;
		cin>>n;
		vector<int> a(n);
		cin>>a;//这波开眼了
		int mn=2e9;
		for (int x:a) if (x&1) cmin(mn,x);//选出最小奇数
		bool fg=0;
		for (int x:{0,1})
		{
			bool flg=1;
			for (int y:a) flg&=(y&1)==x||y>mn;
			fg|=flg;
		}
		if (fg) cout<<"YES\n"; else cout<<"NO\n";
	}
}

D. Flipper

在这里插入图片描述
Example
input

9
5
2 3 1 5 4
9
4 1 6 7 2 8 5 3 9
4
4 3 2 1
2
2 1
6
3 2 4 1 5 6
7
3 2 1 5 7 6 4
10
10 2 5 6 1 9 3 8 4 7
4
4 2 1 3
1
1

output

5 4 1 3 2 
9 4 1 6 7 2 8 5 3 
3 2 1 4 
1 2 
6 5 3 2 4 1 
7 6 4 5 3 2 1 
9 3 8 4 7 1 10 2 5 6 
3 4 2 1 
1 

题意:

给定一排列 P P P
你必须执行如下操作恰好一次
选择 p p p的一个非空子数组 [ l , r ] [l,r] [l,r],翻转;
然后交换 [ 1 , l − 1 ] [1,l-1] [1,l1] [ r + 1 , n ] [r+1,n] [r+1,n]
输出你能得到的字典序最大的结果。

题解:

第一种情况: n = 1 n=1 n=1,直接输出1计科
第二种情况:最大值在开头,那么其实就是 n n n不能作为第一个数,就可以等效于考虑 n − 1 n-1 n1是最大值的情况,考虑其位置再定定情况
第三种情况:最大值在尾巴,就要考虑是否要交换本身,前提是第一个值比最大值前一个位置的值大,这样就直接交换末尾本身就可以了。如果加入了前面的,那么第二个位置一定会少,字典序就不是最大的了
第四种就是一般情况:因为最大值要放在最前面,所以翻转的 [ l , r ] [l,r] [l,r]其中 r r r已经定了。考虑 l l l的位置即可。因为后续调换位置情况,数组开头一定会变到”后面“的开头,如果变的值比数组开头还小的话就不能加入翻转!(这一点看样例6可以很好理解!)
定好 l , r l,r l,r之后进行交换,然后调换前后即可,这里用了旋转数组。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[2020];
void solve(){
    int n;cin>>n;
    for(int i=0;i<n;i++) cin>>a[i];
    vector<int> v;
    int m=max_element(a,a+n)-a;//找最大值
    if(m==0){//最大值在开头
        m=max_element(a+1,a+n)-a;//找下一个最大值
    }
    int l=m-1;
    if(m==n-1&&a[l]<a[0]) l=m;//在最后一位且第一个值最大,交换本身即可[m,m]
    else {
        while(l>0&&a[l-1]>a[0]) l--;
    }
    reverse(a+l,a+m);//交换
    rotate(a,a+l,a+m);//旋转
    rotate(a,a+m,a+n);
    for(int i=0;i<n;i++) cout<<a[i]<<" ";cout<<endl;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;cin>>t;while(t--)
        solve();
    return 0;
}
  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值