首页 > 其他分享 >CF Codeforces Round #843 (Div. 2)

CF Codeforces Round #843 (Div. 2)

时间:2023-01-11 11:47:54浏览次数:58  
标签:843 int ll CF long using Div 数是 define

Codeforces Round #843 (Div. 2)

本次脑袋不大灵光,一方面可能是怕掉分。另一方面就是交的人实在是太少了,导致我一直不敢交,其实这场cf没有我想象中那么难,甚至来说我一直是有思路的,只不过我思考的不全面而已,之后就因为提交的人数过少而一直不敢交。只能说是太垃圾了!

那就稍微写一些题解来看看自己的一些误区吧

1.

A1. Gardener and the Capybaras (easy version)

A2. Gardener and the Capybaras (hard version) time limit per test1 second

本次cfA有两道,每道题是500分,其实不难的

A1和A2的唯一区别是

The only line of a test case contains the string s (3≤|s|≤100) — the names of the capybaras, written together. The string consists of English letters 'a' and 'b' only.
The only line of a test case contains the string s (3≤|s|≤2e5) — the names of the capybaras, written together. The string consists of English letters 'a' and 'b' only.

唯一的区别是两个字符串的大小有区别,这也就导致了如果第一题实在不会写可以暴力,但是第二题不行

首先来看看暴力的解法

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&-(x))
#define endl '\n'
#define int long long
const int INF = 0x3f3f3f3f;
//using ll=long long;
//using ld=long double;
#define PB push_back
#define MK make_paikk
#define EB emplace_back
#define spa " "
#define kkep(i,n,m) fokk(int i=n;i<=m;i++)
#define kkkkep(i,n,m) fokk(ll i = (ll)(m) - 1; i >= (ll)(n); i--)
//using ll = long long;
typedef long long ll;
const int N = 1010;
int  a[N][N];
const int M=10000010;
int b[M];
int n;

void solve() {
    int n,m;
    string s;
    cin>>s;
    string a, b, c;
    for (int i = 0; i < s.size(); i++) {
        for (int j = i+1; j < s.size(); j++) {
            a = s.substr(0, i);
            b = s.substr(i, j-i);
            c = s.substr(j);
            if (!a.empty() && !b.empty() && !c.empty()) {
                if (b <= a && b <= c) {
                    cout << a << " " << b << ' ' << c;
                    return;
                }
                else if (a <= b && c <= b) {
                    cout << a << ' ' << b << ' ' << c;
                    return;
                }
            }
        }
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T;
    cin >> T;
    while (T--)
    {
        solve();
        cout<<endl;
    }
}

对于暴力解法,直接截取片段进行比较即可

由于s最大是100,双重循环并不会TLE,但是对于第二题的大小有2e5,经过双重循环的$O(n^2)$,超出了时间限制

那么怎么解决这个问题呢,一开始其实我的思路是对的,我一开始两种思路,第一个是a是第一个,c是最后一个,b是中间一大串,之后发现这种思路不大对,转而开始第二个思路,a是前面到倒数第二个,b是倒数第二个,c是最后一个。

其实这个思路是对的,但是没有具体分析!!!(我当时但凡脑子仔细想想一些都不至于,那么应该咋写呢?)

分情况讨论一下即可:

来代码:

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&-(x))
#define endl '\n'
#define int long long
const int INF = 0x3f3f3f3f;
//using ll=long long;
//using ld=long double;
#define PB push_back
#define MK make_paikk
#define EB emplace_back
#define spa " "
#define kkep(i,n,m) fokk(int i=n;i<=m;i++)
#define kkkkep(i,n,m) fokk(ll i = (ll)(m) - 1; i >= (ll)(n); i--)
//using ll = long long;
typedef long long ll;
const int N = 1010;
int  a[N][N];
const int M=10000010;
int b[M];
int n;

    void solve(){
        string s;
        cin>>s;
        int n=s.length();
        if(s[0]=='a' && s[n-1]=='a'){
            cout<<s[0]<<" "<<s.substr(1,n-2)<<" "<<s[n-1]<<'\n';
        }
        else if(s[0]==s[n-1]){
            cout<<s.substr(0,n-2)<<" "<<s[n-2]<<" "<<s[n-1]<<'\n';
        }
        else{
            if(s[1]=='a'){
                cout<<s[0]<<" "<<s[1]<<" "<<s.substr(2,n-2)<<'\n';
            }
            else{
                cout<<s[0]<<" "<<s.substr(1,n-2)<<" "<<s[n-1]<<'\n';
            }
        }

    }
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T;
    cin >> T;
    while (T--)
    {
        solve();
    }
}

很容易,我们发现————

  • 如果第一个是a,最后一个也是a,那么b的话我直接输出中间一大串即可,如果中间的是a,三个相等,如果中间的是b,中间的最大,均能满足题目要求
  • 同理,如果第一个是b最后一个也是b的话,a我输出从第一个到倒数第二个数,b是倒数第二个数,c是最后一个数,也就是说当我第一个数是b和最后一个数是b的时候,已经注定了中间的是最小的,那么只要我中间的只输出一个数,无论这个数是a还是b,如果这个数是a那么中间的数最小,如果是b,要么相等要么最小,也都满足题目要求
  • 好了,以上两点其实我都想到了,但是我没有仔细考虑,所以导致我的思路一直不大对
  • 那么之后呢,如果第二个是a的话,那么b就是a,此时b最小,让a是第一个,c是后面一大串就行
  • 如果第二个不是a的话,那么此时不用顾虑第一个和最后一个数是什么了,a是第一个,b 是中间一大串,c是最后一个就行,因为如果第一个数是a,最后一个数是b,那么b就是最大的,如果第一个数是b,最后一个数是a的话,那么中间的数就是也是最大的,因为中间的数是b开头,但是a和c最多一个数还不可能都是b

至此,所有情况都讨论完毕,结束!

所以啊,这道题其实不难的,就是一个思维的问题,尤其是只要想到这个思维,根本不会去想暴力。直接白捡1000分数(bushi)(分数是会慢慢减少的

总体而言,这次的A出的挺有水平的,但是我脑子瓦特了╮(╯_╰)╭

当然除此之外,我当时对于字典序也没有理解对,下面解释一些字典序

字典序

我一开始以为是ASKII码,所以导致一开始我对于题目理解也发生了问题,一开始的思路不对,虽然有点丢脸字典序都不会

2.B. Gardener and the Array

第二题比赛的时候完全没有看,其实第二题也不难的

首先来看看案例

  • input
5
3
2 1 5
2 2 4
2 2 3
2
2 1 2
1 2
4
3 1 2 4
2 2 4
4 1 2 5 6
2 2 5
5
3 3 1 2
3 2 5 3
5 7 2 3 1 4
5 1 2 6 3 5
3 2 6 3
2
1 1
1 2

  • output
No
Yes
Yes
Yes
No

  • 题意

给定$n$ 个整数,每个整数给定的形式是某些位上的数是$1$ ,求能不能从$c$ 中获取 $2 $个子序列,使得两个序列内所有数的$or$ 值相同。

这道题主要是题目一直没有看懂,题目看懂了这道题其实很好理解的,尤其是再配合一下案例

这道题的思路就是找是否有某个串是另外一个数的字串,只要是子串那么当异或之后一定是相同的

  • 分析
    将两个子序列看作两个集合 $a,b$。

尽可能的让其中一个子序列包含尽量多的数,令 $a$集合为 $c$ 内的所有数。接下来我们只需要找到一个没有用的数并把它踢出去就可以,这样的贪心构造是最优秀的,因为一个数对集合的影响是全局的。

如果对于一个数 $c_i$ 的所有位,出现的次数都大于 $1$,那么这个数就是可有可无的,因为一定被 $a$ 这个集合包含,那么 $b$ 集合就是除了$c_i $这个数以外的所有数的集合。构造完毕。

下面给出代码

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&-(x))
#define endl '\n'
#define int long long
const int INF = 0x3f3f3f3f;
//using ll=long long;
//using ld=long double;
#define PB push_back
#define MK make_paikk
#define EB emplace_back
#define spa " "
#define kkep(i,n,m) fokk(int i=n;i<=m;i++)
#define kkkkep(i,n,m) fokk(ll i = (ll)(m) - 1; i >= (ll)(n); i--)
//using ll = long long;
typedef long long ll;
const int N = 1010;
int  a[N][N];
const int M=10000010;
int b[M];
int n;
void solve()
{
    int n;
    cin>>n;
    map<int,int> mp;
    vector<vector<int>> a(n);
    for(int i=0;i<n;i++)
    {
        int k;
        cin>>k;
        for(int j=0;j<k;j++)
        {
            int x;
            cin>>x;
            a[i].push_back(x);
            mp[x]++;
        }
    }
    for(int i=0;i<n;i++)
    {
        bool flag=true;
        for(auto x:a[i])
        {
            if(mp[x]==1)
                flag=false;
           // cout<<x<<" ";
               // cout<<mp[x]<<" ";
        }
       if(flag==true)
        {
            cout<<"YES"<<endl;
            return ;
        }
    }
    cout<<"NO"<<endl;
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T;
    cin >> T;
    while (T--)
    {
        solve();
        cout<<endl;
    }
}

题目理解了其实很好写,直接cheak一下就ok了

标签:843,int,ll,CF,long,using,Div,数是,define
From: https://www.cnblogs.com/jiulics/p/17043252.html

相关文章

  • CF1624 DEG
    D题面大意$n$个字母的字符串,选出$m$个子串(不一定连续,但每个字符串长度至少$1$);子串字母可随意交换;让所有子串都是回文串,而且最短的那个尽可能长。求出最短那......
  • CF843记录
    正序开题A直接做完整版,一开始读错题了以为是任意字符串,想出来之后回去看题,发现只有ab,写了140+行的分讨,20:00才过。B又读错题以为是异或,想了一会儿发现读错题了,水题......
  • Codeforces Round #843 (Div. 2) 做题记录
    CodeforcesRound#843(Div.2)做题记录A1&A2.GardenerandtheCapybarasProblemCF1775A2GardenerandtheCapybaras题目大意:给你一个由a和b组成的字符串,要......
  • Codeforces Round #843 (Div. 2) C【思维】
    https://codeforces.com/contest/1775/problem/C题意题意是说,给你n和x,你要求出最小的满足要求的m,使得\(n\)&\((n+1)\)&\((n+2)\)&\(...\)&\(m=x\)若没有满足的输出-1......
  • Codeforces Round #843 (Div. 2) A~E
    A.GardenerandtheCapybaras这道题目就是想让我们输出三个字符串,然后又一个要求就是中间这个字符串具有最值(最大或最小)的字典序这里需要注意一下,这个字符串里面只有a......
  • CF1761F Anti-median (Easy Version)
    称一个排列是好的,当且仅当对于所有\(m\)都满足所有长度为\(2m+1\)的子串的中位数不在第\(m+1\)个。给定一个一些数被替换成\(-1\)的排列\(p\),你需要统计所有可能......
  • Educational Codeforces Round 141 (Rated for Div. 2)
    比赛链接;A核心思路:其实我们不要被迷惑了,这就是一个构造题。如果遇到构造题没有思路的话。可以联想经典的构造。也就是一大一小进行构造。然后检查是否可行。//Problem:......
  • Codeforces Round #843 (Div. 2)
    CodeforcesRound#843(Div.2)https://codeforces.com/contest/1775CD都不会写的垃圾罢了A1.GardenerandtheCapybaras(easyversion)#include<bits/stdc++.h>......
  • Codeforces Round #843 (Div. 2) 题解
    A题目大意给你一个只含字母a,b字符串,要把它拆分成三段,使得其中间那段要么同时小于等于两边要么同时大于等于两边。题解由于只有a,b我们可以分讨解决如果\([2,......
  • CF1783 A-F 题解
    比赛链接:https://codeforces.com/contest/1783连续三场出4题,还行(其实感觉有两场的E都是会做的)A水题//bySkyRainWind#include<bits/stdc++.h>#definemprmake_pai......