牛客周赛34(A-E)

目录

1.A

2.B

3.C

4.D

 5.E


这场出题人号称是考思维,把我给搞蒙了,把我这菜鸡实力暴露的淋漓尽致,不过这场还是让我学到了东西.A,B题就是签到题,会语法就能做(doge),c题我知道思路是啥,但我没想到切分出来的偶数也可能爆long long,所以还得用字符串存,自定义cmp比较函数,而我却是用long long存,用multiset排序,最后得了大部分分(泪目).D题就是分类讨论,没有清晰的头脑简直让人头皮发麻,E题是个二分图,没学过,FG太难了,不是我能涉及的.

1.A

#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int n;
    cin>>n;
    set<int>st;
    for(int i=1;i<=n;i++)
    {
        int t;
        cin>>t;
        if(t<=n&&t>=1)
        st.insert(t);
    }
    if(st.size()!=n)
    cout<<0;
    else
    {
        cout<<1<<"\n";
        cout<<1<<" "<<100005;
    }
    return 0;
}

2.B

#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    char a,b;
    cin>>a>>b;
    if(a!=b)
    {
    cout<<4<<"\n";
    cout<<a<<b<<"\n";
    cout<<b<<a<<"\n";
    cout<<a<<"\n";
    cout<<b<<"\n";
    }
    else
    {
        cout<<2<<"\n";
        cout<<a<<"\n";
        cout<<a<<a<<"\n";
    }
    return 0;
}

3.C

这题的思路就是从前向后遍历,遇到偶数就分割,(别问我可不可能出现一个奇数落单无法变成偶数的,这样这题就没答案了),然后将切割的字符串扔进一个数组,最后排个序就行

#include<bits/stdc++.h>
using namespace std;
#define int long long
bool cmp(string m,string n)
{
    if(m.size()!=n.size())return m.size()<n.size();
    else return m<n;
}
signed main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    //遇到偶数就切割
    string s;
    cin>>s;
    string temp;
    vector<string>v;
    for(auto i:s)
    {
        if((i-'0')%2==0)
        {
            temp+=i;
            v.push_back(temp);
            temp="";
        }
        else
        {
            temp+=i;
        }
    }
    sort(v.begin(),v.end(),cmp);
    for(auto i:v)
    {
        cout<<i<<"\n";
    }
    return 0;
}

4.D

首选要知道答案长啥样,因为陡峭值恰好为1,所以只能是1,1,1,2,2或2,2,1,1这两种情况(当然这里的1和2只是泛指最大值和最小值)

由此开始讨论

1.ma-mi>1,无解

2.ma-mi==1,找出最大值和最小值的分界点,如果是混乱的则无解,否则分ma在前mi在后,mi在前ma在后两种情况进行讨论,输出答案
 

当然,本题最恶心的是要特判全0的情况,输出2 1 1 1 ....即可 

#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int n;
    cin>>n;
    vector<int>v(n);
    int ma=-1,mi=10000000000;
    for(int i=0;i<n;i++)
    {
        cin>>v[i];
        if(v[i]!=0)
        {
            ma=max(ma,v[i]);
            mi=min(mi,v[i]);
        }
    }
    if(ma==-1)
    {
        cout<<2<<" ";
        for(int i=0;i<n-1;i++)cout<<1<<" ";
        return 0;
    }
    //cout<<mi<<" "<<ma<<"\n";
    if(ma-mi>1)//最大值最小值的差超过1无解
    {
        cout<<-1;
    }
    else if(ma-mi==1)//最大值最小值的差恰好为1
    {
        vector<int>v1,v2;
        for(int i=0;i<n;i++)
        {
            if(v[i]==mi)v1.push_back(i);//为mi的下标
            if(v[i]==ma)v2.push_back(i);//ma的下标
        }
        //cout<<mi<<" "<<ma<<" "<<v1[0]<<" "<<v2[0]<<"\n";
        if(v1.back()<v2[0])
        {
            int k;
            for(k=0;k<=v1.back();k++)cout<<mi<<" ";
            for(;k<n;k++)cout<<ma<<" ";
        }
        else if(v2.back()<v1[0])
        {
            int k;
            for(k=0;k<=v2.back();k++)cout<<ma<<" ";
            for(;k<n;k++)cout<<mi<<" ";
        }
        else
        {
            cout<<-1;
        }
    }
    else
    {
        if(v[0]!=0&&v[n-1]!=0)
        {
            cout<<-1;
        }
        else if(v[0]==0)
        {
            cout<<mi+1<<" ";
            for(int i=0;i<n-1;i++)
            cout<<mi<<" ";
        }
        else if(v[n-1]==0)
        {
            for(int i=0;i<n-1;i++)
            cout<<mi<<" ";
            cout<<mi+1<<" ";
        }
    }
    return 0;
}

 5.E

这题是个二分图,因为只有两种字符'd','p',所以每一层必须是一样的字母,而且相邻两层的字母必定不同,我们可以将奇数层打成1标记,偶数层打成0标记,那么'd'字符和'p'字符必须分别在奇数层或偶数层,

所以p的标记只能有一个,d的标记也只能有一个,不满足这种情况直接无解,反之有解,根据打的标记输出d或p即可

#include<bits/stdc++.h>//二分图
using namespace std;
#define int long long
const int maxn=1e5+5;
vector<int>g[maxn];
int dp[maxn];
void dfs(int x,int pr,int p)
{
    dp[x]=p;
    for(auto i:g[x])
    {
        if(i==pr)continue;
        dfs(i,x,1-p);
    }
}//dfs遍历树
signed main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int n;
    cin>>n;
    string s;
    cin>>s;
    s=' '+s;
    for(int i=0;i<n-1;i++)
    {
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }//建图
    set<int>d,p;
    dfs(1,0,1);
    for(int i=1;i<=n;i++)
    {
        if(s[i]=='d')d.insert(dp[i]);
        if(s[i]=='p')p.insert(dp[i]);
    }
    if(d.size()>1||p.size()>1)
    {
        cout<<-1;
        return 0;
    }
    // else if(d.size()==1&&p.size()==1&&(*d.begin()==*p.begin()))
    // {
    //     cout<<-1;
    // }
    if(*d.begin()==1)
    {
        for(int i=1;i<=n;i++)
        {
            if(dp[i]==1)cout<<'d';
            else cout<<"p";
        }
    }
    else 
    {
        for(int i=1;i<=n;i++)
        {
            if(dp[i]==1)cout<<"p";
            else
            cout<<"d";
        }
    }
    return 0;
}

写在最后:

本人实力比较菜,如有错误,欢迎指出,如果觉得看不懂,烦请参考其他大佬的思路

  • 17
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
牛客 a卷2022年第四季度的华为题目中,要求考生设计一种高效的数据结构,能够支持以下几种操作: 1. 添加一个元素 2. 删除一个元素 3. 查找是否存在某个元素 4. 返回元素的总数 该数据结构要求满足空间复杂度较小、时间复杂度较低、能够快速地进行查找和修改等多种操作。 想要编写这样一种数据结构,我们可以参考许多已有的经典算法数据结构,如二叉树、哈希表、红黑树等,通过综合利用它们的优点来实现这个问题的解决。 例如,我们可以通过哈希表来存储所有元素的值,并在每个哈希链表的元素中再使用红黑树来进行排序与查找。这样,我们既能够轻松地进行元素的添加和删除操作,也能够在查找较大数据范围和数量时保持较高的速度与效率。同时,由于使用了多个数据结构来协同完成这个问题,我们也能够在空间复杂度上适度地进行优化。 当然,在具体设计这个数据结构的过程中,我们还需要考虑一些实践中的细节问题,例如如何避免哈希冲突、如何处理数据丢失与被删除元素所占用的空间等问题,这都需要相应的算法与流程来进行处理。 总体来看,设计这种支持多种操作的高效数据结构,需要我们具备丰富的算法知识和编程实践能力,同时需要我们在具体处理问题时能够将多种算法数据结构进行有效地结合。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值