牛客周赛Round35

文章主要介绍了五个C++编程题目,涉及字符串切割、数组分配策略、查找特定条件下的鸡的数量、排列构造、无向图构建以及子序列权值和的计算,展示了不同类型的算法和数据结构应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A 小红的字符串切割

签到题

#include<bits/stdc++.h>
#define endl "\n"
#define pb push_back
#define ALL(x) x.begin(),x.end()
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
typedef pair<int,int> pii;
const int inf=INT_MAX;
const int mod=1e9+7;
const int maxn=1e5+7;

void solve()
{
    string s;
    cin>>s;
    int len=s.size();
    string a=s.substr(0,len/2);
    string b=s.substr(len/2,len/2);
    cout<<a<<endl<<b<<endl;
}

signed main()
{   
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();
    return 0;
}

B 小红的数组分配

签到题

#include<bits/stdc++.h>
#define endl "\n"
#define pb push_back
#define ALL(x) x.begin(),x.end()
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
typedef pair<int,int> pii;
const int inf=INT_MAX;
const int mod=1e9+7;
const int maxn=1e5+7;

void solve()
{
    int n;
    cin>>n;
    n=n*2;
    vector<ll> v;
    map<ll,int> mp;
    for(int i=1;i<=n;i++)
    {
        ll t;
        cin>>t;
        v.pb(t);
        mp[t]++;
    }
    vector<ll> ans;
    for(auto i:mp)
    {
        if(i.second%2==1){cout<<-1<<endl;return;}
        else
        {
            int time=i.second/2;
            for(int j=1;j<=time;j++)
            {
                ans.pb(i.first);
            }
        }
    }
    ll len=ans.size();
    for(int i=0;i<len;i++)
    {
        if(i!=len-1)    cout<<ans[i]<<" ";
        else    cout<<ans[i]<<endl;
    }
    for(int i=0;i<len;i++)
    {
        if(i!=len-1)    cout<<ans[i]<<" ";
        else    cout<<ans[i]<<endl;
    }
}

signed main()
{   
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();
    return 0;
}

C 小红关鸡

签到题

#include<bits/stdc++.h>
#define endl "\n"
#define pb push_back
#define ALL(x) x.begin(),x.end()
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
typedef pair<int,int> pii;
const int inf=INT_MAX;
const int mod=1e9+7;
const int maxn=1e5+7;

void solve()
{
    ll n,k;
    cin>>n>>k;
    vector<ll> v;
    for(int i=1;i<=n;i++)
    {
        ll t;
        cin>>t;
        v.pb(t);
    }
    sort(ALL(v));
    ll ans=-inf;
    for(int i=0;i<v.size();i++)
    {
        ll cnt=lower_bound(v.begin()+i,v.end(),v[i]+k+1)-(v.begin()+i);
        ans=max(ans,cnt);
    }
    cout<<a1*1.0/(a2*1.0)<<endl;

}

signed main()
{   
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();
    return 0;
}

D 小红的排列构造

贪心

#include<bits/stdc++.h>
#define endl "\n"
#define pb push_back
#define ALL(x) x.begin(),x.end()
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
typedef pair<int,int> pii;
const int inf=INT_MAX;
const int mod=1e9+7;
const int maxn=1e5+7;

void solve()
{
    int n;
    cin>>n;
    map<ll,int> mp;
    vector<int> v(n+1);
    for(int i=1;i<=n;i++)
    {
        cin>>v[i];
        mp[v[i]]++;
    }
    int cnt=0;
    vector<int> tem;
    for(int i=1;i<=n;i++)//找到所有需要转换的数,保存
    {
        if(mp[i]==0)
        {
            cnt++;
            tem.pb(i);
        }
    }
    int len=tem.size();//需要转换的目标数字的数量
    cout<<cnt<<endl;//最少需要的次数
    int pos=0;
    for(int i=1;i<=n;i++)
    {
        if(v[i]>n || mp[v[i]]>1)//从头遍历 v 数组,如果这个数大于 n 或者在整个数组中该数字的个数大于 1 就把他转换,并且使其在 mp 容器中的数量减 1
        {
            cout<<i<<" "<<tem[pos++]<<endl;
            mp[v[i]]--;
        }
        if(pos==len)    break;//所有的数字都转换完毕
    }
}

signed main()
{   
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();
    return 0;
}

E 小红的无向图构造

思维、构造、分类讨论

#include<bits/stdc++.h>
#define endl "\n"
#define pb push_back
#define ALL(x) x.begin(),x.end()
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
typedef pair<int,int> pii;
const int inf=INT_MAX;
const int mod=1e9+7;
const int maxn=1e5+7;

vector<int> g[maxn];//子序列自动机,g 用来存到节点 1 距离为 i 的节点
int a[maxn];
void solve()
{
    int n,m;
    int ma=0;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        g[a[i]].pb(i);
        ma=max(ma,a[i]);//节点最大值
    }
    if(m<n-1){cout<<-1<<endl;return;}//如果m<n-1肯定建不了图
    vector<pii> ans;
    for(int i=1;i<=ma;i++)//初始建图
    {
        if(g[i].empty())//必须是 0 1 2 3 ...这样的,不能有断层,否则无法组成
        {
            cout<<-1<<endl;
            return;
        }
        else
            for(int j=0;j<g[i].size();j++)//建图
            {
                ans.pb({g[i-1][0],g[i][j]});
            }
    }
    if(ans.size()<m)//边的数量不够的处理方法
    {
        for(int i=1;i<=ma;i++)//同距离处理
        {
            for(int j=0;j<g[i].size();j++)
            {
                for(int k=j+1;k<g[i].size();k++)
                {
                    ans.pb({g[i][j],g[i][k]});
                    if(ans.size()==m)   break;
                }
                if(ans.size()==m)   break;
            }
            if(ans.size()==m)   break;
        }
        for(int i=1;i<=ma;i++)//距离差为 1 处理
        {
            for(int j=1;j<g[i].size();j++)//因为之前建图的时候都把距离为 x 的点连在距离 x-1 的第一个点上,所以这里 j 从 1 开始,避免重复连接
            {
                for(auto k:g[i+1])
                {
                    ans.pb({g[i][j],k});
                    if(ans.size()==m)   break;
                }
                if(ans.size()==m)   break;
            }
            if(ans.size()==m)   break;
        }
    }
    if(ans.size()<m)
    {
        cout<<-1<<endl;
        return;
    }
    else
    {
        for(auto i:ans)
        {
            cout<<i.first<<" "<<i.second<<endl;
        }
    }
}

signed main()
{   
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();
    return 0;
}

F 小红的子序列权值和(easy)

数论

#include<bits/stdc++.h>
#define endl "\n"
#define pb push_back
#define ALL(x) x.begin(),x.end()
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
typedef pair<int,int> pii;
const int inf=INT_MAX;
const int mod=1e9+7;
const int maxn=1e5+7;

//结论: x=p1^a1 * p2^a2
//其因子数量为 =(a1+1)*(a2+1);
ll C[1010][1010];
void solve()
{
    int n;
    map<int,int> mp;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int t;
        cin>>t;
        mp[t]++;
    }
    int tem=1;
    for(int i=1;i<=mp[1];i++)
    {
        tem*=2;
        tem%=mod;
    }
    for(int i=0;i<=n;i++)
    {
        for(int j=0;j<=i;j++)
        {
            if(j==0 || j==i)    C[i][j]=1;
            else C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
        }
    }
    ll ans=0;
    for(int i=0;i<=mp[2];i++)
    {
        for(int j=0;j<=mp[3];j++)
        {
            ans+=(C[mp[2]][i]*C[mp[3]][j])%mod*tem%mod*(i+1)%mod*(j+1)%mod;
        }
    }
    cout<<(ans-1)%mod<<endl;
}

signed main()
{   
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();
    return 0;
}

G 小红的子序列权值和(hard)

数论、除法逆元优化

#include<bits/stdc++.h>
#define endl "\n"
#define pb push_back
#define ALL(x) x.begin(),x.end()
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
typedef pair<int,int> pii;
const int inf=INT_MAX;
const int mod=1e9+7;
const int maxn=1e5+7;

//结论: x=p1^a1 * p2^a2
//其因子数量为 =(a1+1)*(a2+1);
ll quick_pow(ll a,ll b)
{
    ll ans=1;
    while(b){
        if(b&1) ans=(ans*a)%mod;
        b>>=1;
        a=(a*a)%mod;
    }
    return ans;
}
ll inv(ll a,ll b)
{
    return (a*quick_pow(b,mod-2))%mod;
}
ll jc[maxn];
int n;
ll C(int n,int m)
{
    return inv(jc[n],jc[n-m]%mod*jc[m]%mod);
}
void solve()
{
    map<int,int> mp;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int t;
        cin>>t;
        mp[t]++;
    }
    int tem=1;
    for(int i=1;i<=mp[1];i++)
    {
        tem*=2;
        tem%=mod;
    }
    jc[0]=1;
    for(int i=1;i<=n;i++)
    {
        jc[i]=jc[i-1]*i%mod;
    }
    ll ans=0,c2=0,c3=0;
    for(int i=0;i<=mp[2];i++){
        c2+=C(mp[2],i)*(i+1)%mod;
        c2%=mod;
    }
    for(int i=0;i<=mp[3];i++){
        c3+=C(mp[3],i)*(i+1)%mod;
        c3%=mod;
    }
    cout<<(c2*c3%mod*tem%mod-1+mod)%mod;
}

signed main()
{   
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();
    return 0;
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值