牛客周赛 Round 82 -- 题解

A-夹心饼干_牛客周赛 Round 82

思路:第一个和第三个字母相等就行

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

int main()
{
	string s;
    cin>>s;
    
    if(s[0] == s[2])cout<<"YES";
    else cout<<"NO";
	return 0;
} 

B-食堂大作战1.0_牛客周赛 Round 82

思路:都同时减去1人,所以不能有相同人数的队伍

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

int main()
{
	int n;
    cin>>n;
    set<int> hash;
    
    bool flag=true;
    for(int i=0;i<n;i++)
    {
        int a;
        cin>>a;
        
        if(hash.count(a))flag=false;
        
        hash.insert(a);
    }
    
    if(flag)cout<<"YES";
    else cout<<"NO";
    
	return 0;
} 

C-食堂大作战2.0_牛客周赛 Round 82 

思路:人少的先排,记录一下下标即可

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

int main()
{
	int n;
    cin>>n;
    set<int> hash;
    map<int,int> m;
    
    bool flag=true;
    for(int i=1;i<=n;i++)
    {
        int a;
        cin>>a;
        
        if(hash.count(a))flag=false;
        
        hash.insert(a);
        m[a]=i;
    }
    
    if(flag)
    {
        cout<<"YES"<<endl;;
        for(auto &[k,v]:m)
        {
            cout<<v<<" ";
        }
    }
    else cout<<"NO";
    
	return 0;
} 

D-小苯的排列计数_牛客周赛 Round 82

保持递减 , 不递减就无法构造。

方法1最后一个测试案例错了 , 不知道为什么 ^ ^

方法二是对的

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353;

int main()
{
	int t;
    cin>>t;
    
    while(t--)
    {
//         //方法1  不正确
//         int n;
//         cin>>n;
        
//         vector<int> nums(n);
        
//         for(int i=0;i<n;i++)
//         {
//             cin>>nums[i];
//         }
        
//         vector<int> ans;
//         vector<bool> pos(n+1,true);
//         int ma=INT_MAX;
//         for(int i=0;i<n;i++)
//         {
//             if(nums[i] < ma)
//             {
//                 pos[nums[i]]=false;
//                 ma=min(ma,nums[i]);
//             }
//             else
//             {
//                 ans.push_back(nums[i]);
//             }
//         }
        
//         vector<int> back_(n+1,0);
//         for(int i=n-1;i>=0;i--)
//         {
//             if(pos[i+1])
//             {
//                 back_[i]++;
//             }
//             back_[i]+=back_[i+1];
//         }
        
//         int k=0;
//         int res=1;
//         for(int i=0;i<ans.size();i++)
//         {
//             res = ((ll)res * max(0,(back_[ans[i]]-k)))%mod;
//             k++;
//         }
        
//         cout<<res<<endl;
        
        //方法2  正确
        int n;
        cin>>n;
        
        vector<int> nums(n);
        for(int i=0;i<n;i++)
        {
            cin>>nums[i];
        }
        
        ll ans=1;
        ll select=n-nums[0];
        bool flag=true;
        for(int i=1;i<n;i++)
        {
            if(nums[i] == nums[i-1])
            {
                ans = (ans * select) % mod;
                select--;
            }
            else if(nums[i] > nums[i-1])
            {
                flag=false;
                break;
            }
            else
            {
                select += nums[i-1] - nums[i] - 1;
            }
        }
        if(flag)
        cout<<ans%mod<<endl;
        else
        cout<<0<<endl;
    }
    
	return 0;
} 

E-和+和_牛客周赛 Round 82

看注释

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
	int n,m;
    cin>>n>>m;
    
    vector<int> a(n+1);
    vector<int> b(n+1);
    
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<=n;i++)
    {
        cin>>b[i];
    }
    
    //用优先队列,维护前m的最小值的和,
    // 数组aa定义为下标从1 ~ i的最小m个之和
    vector<ll> aa(n+1,0);
    ll suma=0;
    priority_queue<int> pqa;
    
    //先维护m个
    for(int i=1;i<=m;i++)
    {
        suma+=a[i];    
        pqa.push(a[i]);
    }
    aa[m] = suma;   // 1 ~ m位置  
    
    //先加上当前值 ,放入优先队列 , 再从优先队列的最上面拿最大值 减去
    //如果当前值是最大值 , 就又减去  , 还是原来的最小值
    //如果当前值不是最大值 , 就减小了一点最小值 , 得到比原来更小的更小值
    for(int i=m+1;i<=n-m;i++)
    {
        suma+=a[i];
        pqa.push(a[i]);
        suma-=pqa.top();
        pqa.pop();
        
        aa[i] = suma;
    }
    
    //为什么从后往前?   题目要求下标递增 , 
    //a选m个 , b选m个 ,所以b要从a的m个的最后应该下标的下一个开始找
    // 例:  a选的是 1 - 3 的m个数最小值和  b要从 4 - n  中选m个
    
    //数组bb同上 , 但注意是从后往前 , 数组bb维护 i ~ n 的m的最小值
    vector<ll> bb(n+1,0);
    ll sumb=0;
    priority_queue<int> pqb;
    
    for(int i=n;i>=n-m+1;i--)
    {
        sumb+=b[i];
        pqb.push(b[i]);
    }
    
    bb[n-m+1] = sumb;
    
    for(int i=n-m;i>=m;i--)
    {
        sumb+=b[i];
        pqb.push(b[i]);
        sumb-=pqb.top();
        pqb.pop();
        
        bb[i] = sumb;
    }
    
    //      aa1  aa2  aa3  aa4  aa5
    //范围  1-1  1-2  1-3  1-4  1-5
    //      bb1  bb2  bb3  bb4  bb5
    //范围  1-5  2-5  3-5  4-5  5-5
    
    //所以应该斜着相加求最小值
    
    ll ans=INT_MAX;
    for(int i=m;i<=n-m;i++)
    {
        ans = min(ans,aa[i]+bb[i+1]);
    }
    
    cout<<ans<<endl;
    
	return 0;
} 

F-怎么写线性SPJ_牛客周赛 Round 82

打表 , 贪心找规律

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

int main() {
    int n;
    cin >> n;  
    int k;
    string s = "1";  //一个数时的最小
    int i = 2;  
    while (s.size() < n) {
        char c = '0' + i; 
        s = s + c + s;  
        i += 1; 
    }
    cout << i-1 << endl; 
    for (int i = 0; i < n; i++) {
        cout << s[i] - '0' << " "; //换回数字
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值