CF Codeforces Round #843 (Div. 2)

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了

posted @   jiulics  阅读(53)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示