[2021] 牛客模考(二模)编程题集合

第1题

在这里插入图片描述

输入描述:

本题为多组测试数据,第一行输入一个正整数,代表测试数据组数。

对于每组测试数据,一行输入一个长度不超过100001串,代表初始形态。

输出描述:

对于每组测试数据,如果牛妹得分高,则在第一行输出NiuMei,第二行输出一个分数代表牛妹比牛牛高几分;
如果牛牛得分高,则在第一行输出NiuNiu,第二行输出一个分数代表牛牛比牛妹高几分;
如果两个人分数相同,则只需要在一行输出Draw.

输入例子1:

2
111111
111011

输出例子1:

Niumei
6
Niumei
1

例子说明1:

第一个测试数据中,牛妹可以一次性消除所有字符,得到6分,而牛牛0 分。
第二个测试数据中,牛妹先消除前三个字符,得到3 分,剩余字符为011,牛牛选择末尾两个字符消除,得到2分,至此,字符只剩下0,牛妹消除掉这个字符,但由于该字符是0,所以不得分。总计牛妹得到3分,牛牛得到2分。

我的代码

#include <iostream>
#include <string>
#include <string.h>
#include <stdio.h>

using namespace std;

int myremove(string& str)
{
    //记得排除极端情况,全0或全1


    //找字符串的最长1相同子字符串,记录其起始位置和结束位置
    //先消除1
    int a[(const int)str.size()];
    memset(a, 0x0000, sizeof(a));//数组a[i]表示以str[i]结尾的子字符串中连续1的个数

    for(int i = 0; i < str.size(); i++)
    {
        if(str[i] == '1')
            a[i] = 1;
    }

    for(int i = 1; i < str.size(); i++)
    {
        if(str[i] == '1' && str[i-1] == str[i])
            a[i] = a[i-1] + 1;

    }

    //找a[]中的最大值
    int index = 0, val = a[0];
    for(int i = 0; i < str.size(); i++)
    {
        if(a[i] > val)
        {
            val = a[i];
            index = i;
        }
    }


    if(val == 0)
        return -1;

    string new_str;
    //下标i=index-val...index这段不要
    new_str = str.substr(0, index-val+1) + str.substr(index+1);
    str.clear();
    str = new_str;

    return val;
}

int main()
{
    int T;
    cin >> T;
    while(T--)
    {
        string str;
        cin >> str;
        int mei = 0, niu = 0;
        while(str.size() != 0)
        {
            int add1 = myremove(str);
            if(add1 == -1) break;
            mei += add1;
            int add2 = myremove(str);
            if(add2 == -1) break;//没有1时返回-1
            niu += add2;
        }
         
        if(mei > niu)
        {
            cout << "Niumei" << endl;
            cout << mei - niu << endl;
        }
        else if(mei < niu)
        {
            cout << "NiuNiu" << endl << niu - mei << endl;
        }
        else
            cout << "Draw" << endl;
         
    }
     
     
    return 0;
}

第2题

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

我的代码

#include <iostream>
#include <algorithm>
#include <string>
#include <unordered_map>
#include <queue>

using namespace std;

const int N = 100010;
int attack[N];
int money[N];
int res[N];//存放每个猎人能够获得的最大金钱
unordered_map<int, int> h;
int n, k;


int main()
{
    cin >> n >> k;
    
    for(int i = 0; i < n; i++)
    {
        int tmp;
        cin >> tmp;
        attack[i] = tmp;
        h[tmp] = i;
    }
    
    for(int i = 0; i < n; i++)
    {
        int tmp;
        cin >> tmp;
        money[i] = tmp;
        res[i] = tmp;
    }
    
    //如果k等于0,直接输出res
    if(k == 0)
    {
        for(int i = 0; i < n; i++)
            cout << res[i] << ' ';
        cout << endl;
        return 0;
    }
    
    
    
    sort(attack, attack+n);//对攻击力从小到大排序,按照h[attack[i]]可知道attack[i]在原数组中的下标
    
    
    priority_queue<int, vector<int>, greater<int>> q;
    //小根堆q,堆顶存放最小值。用来维护k个最大金额。
    int sum = 0;//存储k个最大金额之和
    for(int i = 1; i < n; i++)
    {
        int val = money[h[attack[i-1]]];
        if(q.size() < k)
        {
            sum += val;
            q.push(val);
        }
        else
        {
            if(q.top() < val)
            {
                sum -= q.top();
                sum += val;
                q.pop();
                q.push(val);
            }
        }
            
        res[h[attack[i]]] += sum; 
        
    }
    
    for(int i = 0; i < n; i++)
        cout << res[i] << ' ';
    cout << endl;
    
    return 0;
    
    
}

第3题

在这里插入图片描述
在这里插入图片描述

考察字典树trie,它用来高效地存储和查找字符串。

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 1e7 + 10;//10^5个字符串,每个字符串18位,每位最多有10个字结点,故10^7
int son[N][10];//字典树,第1个参数表示结点序号,第2个参数表示该结点的可能存在的子结点编号,值表示存在的子结点序号
//对于结点x,son[x][0]表示结点x的第0个子结点,son[x][1]表示结点x的第1个子结点...
//如果son[x][1] == 0,表示结点x的第1个子结点为空!
//注意根结点也用0表示!
int cnt[N];
//原字典树中cnx[x]表示以结点x结尾的单词有多少个
//在这里做了变形,cnt[x]表示经过结点x的单词个数
int idx;//表示当前用到了哪个结点
int n, m;

void insert(string str)
{
    int p = 0;
    for(int i = 0; i < str.size(); i++)
    {
        int u = str[i] - '0';
        if(!son[p][u]) son[p][u] = ++idx;
        cnt[son[p][u]]++;
        p = son[p][u];
    }
}

void query(string str, int& k, int& num)//k表示最大相似度,num表示次数
{
    int p = 0;
    num = n;
    for(int i = 0; i < str.size(); i++)
    {
        int u = str[i] - '0';
        if(!son[p][u])//如果子节点son[p][u]不存在
        {
            k = i;//不存在完全相同的身份证,所以k=18不用考虑
            return;
        }
        num = cnt[son[p][u]];
        p = son[p][u];
    }
    return;
}


int main()
{
    cin >> n >> m;
    string str;
    int t = n;
    while(t--)
    {
        cin >> str;
        insert(str);
    }
    
    t = m;
    while(t--)
    {
        cin >> str;
        int k, num;
        query(str, k, num);
        cout << k << " " << num << endl;
    }
    
    return 0;
}

待更新

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YMWM_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值