2024牛客多校训练营第五场

目录

赛时解决题目:B,E,H,L

E:

        题意:

        解题思路:

L:

        题意:

         解题思路:

B:

        题意:

        解题思路:

H:

        题意:

        解题思路:


赛时解决题目:B,E,H,L

E:

        题意:给两行n个骑士,第一行第i个与第二行第i个面对面,每个骑士都有血条h[i]。由第一行先开始,选择一个存活骑士的下标,扣对应的对面一个骑士一滴血,接下来轮到第二行,轮流。双方都已己方骑士剩余数量最大化为目标,问第一行最后剩下多少骑士。

        解题思路:很明显,如果a[i]>b[i],那么a[i]肯定能战胜b[i],如果a[i]==b[i],那么谁先手谁能存活

        

#include<bits/stdc++.h>
#define endl '\n'
#define ll int
#define int long long
#define double long double
#define Int __int128
#define pb push_back
#define N (int)3e5+10
#define MAX_LOG 21
#define ff first
#define ss second
#define M 5005
#define ull unsigned long long
using namespace std;
const double PI=3.1415926535897932385;
const ll LLMAX=9223372036854775807ll;
const ll LLMIN=-9223372036854775808ll;
//const int MAX_INT=0x3f3f3f3f;
const int IIMAX=2147483647;
const int IIMIN=-2147483648;
const int INF=0x3f3f3f3f;
typedef pair<ll,ll> PLL;
ll gcd(ll a,ll b)
{
    if(b) while((a%=b)&&(b%=a));
    return a+b;
}//最大公约数函数
ll spid(ll a,ll b,ll p)
{
    ll ans=1;
    while(b)
    {
        if(b&1)ans=ans*a%p;
        b>>=1;
        a=a*a%p;
    }
    return ans;
}//快速幂函数
///泡沫在阳光下闪烁,像星辰在寂静得夜空中闪耀

///秋雨
ll a[N];
ll b[N];
void solve()
{
    ll n;cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++)cin>>b[i];
    bool ret=1;
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        if(a[i]>b[i])ans++;
        else if(a[i]==b[i])
        {
            ans+=ret;
            ret^=1;
        }
    }
    cout<<ans<<'\n';
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t=1;
    cin>>t;
    while(t--)
    {
        solve();
    }
}
///在秋天邂逅, 在春天发芽,在夏天壮大,在秋天萧瑟,在冬天萎缩,

///而后,春天再度归来。



L:

        题意:给你长度为n的数组,a[i]>0&&a[i]<=100,你可以进行任意次操作,选择一个下标i(0<i<n),让a[i+1]--,a[i]++。问这个数组的最大乘积是多少。

         解题思路:我们肯定希望每个数字尽可能相等,发现数据很小,尽可能取均值即可。

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define int long long
#define double long double
#define Int __int128
#define pb push_back
#define N (int)3e5+10
#define MAX_LOG 21
#define ff first
#define ss second
#define M 5005
#define ull unsigned long long
using namespace std;
const double PI=3.1415926535897932385;
const ll LLMAX=9223372036854775807ll;
const ll LLMIN=-9223372036854775808ll;
//const int MAX_INT=0x3f3f3f3f;
const int IIMAX=2147483647;
const int IIMIN=-2147483648;
const int INF=0x3f3f3f3f;
typedef pair<ll,ll> PLL;
ll gcd(ll a,ll b)
{
    if(b) while((a%=b)&&(b%=a));
    return a+b;
}//最大公约数函数
ll spid(ll a,ll b,ll p)
{
    ll ans=1;
    while(b)
    {
        if(b&1)ans=ans*a%p;
        b>>=1;
        a=a*a%p;
    }
    return ans;
}//快速幂函数
///泡沫在阳光下闪烁,像星辰在寂静得夜空中闪耀

///秋雨
ll a[N];
ll p=998244353;
void solve()
{
    ll n;
    cin>>n;
    for(int i=1; i<=n; i++)cin>>a[i];
    while(1)
    {
        ll ret=1;
        for(int i=n;i>1;i--)
        {
            if(a[i]>a[i-1])
            {
                ret=0;
                ll sum=a[i]+a[i-1];
                a[i]=sum>>1;
                a[i-1]=sum-a[i];
            }
        }
        if(ret) break;
    }
    ll ans=1;
    for(int i=1;i<=n;i++)
    {
        ans*=a[i];
        ans%=p;
    }
    cout<<ans<<'\n';
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t=1;
    cin>>t;
    while(t--)
    {
        solve();
    }
}
///在秋天邂逅, 在春天发芽,在夏天壮大,在秋天萧瑟,在冬天萎缩,

///而后,春天再度归来。



B:

        题意:你有无数块长为2,宽为1的多米诺骨牌,给你一个n*m的矩阵,问你能不能用这种多米诺骨牌拼成这个矩阵。

        可能有两个限制:

        限制1:短边不能和短边完整共用一条边

        限制2:长边不能和长边完整共用一条边

        解题思路:针对各种情况特判即可。

#include<bits/stdc++.h>
#define endl '\n'
#define ll int
#define int long long
#define double long double
#define Int __int128
#define pb push_back
#define N (int)3e5+10
#define MAX_LOG 21
#define ff first
#define ss second
#define M 5005
#define ull unsigned long long
using namespace std;
const double PI=3.1415926535897932385;
const ll LLMAX=9223372036854775807ll;
const ll LLMIN=-9223372036854775808ll;
//const int MAX_INT=0x3f3f3f3f;
const int IIMAX=2147483647;
const int IIMIN=-2147483648;
const int INF=0x3f3f3f3f;
typedef pair<ll,ll> PLL;
ll gcd(ll a,ll b)
{
    if(b) while((a%=b)&&(b%=a));
    return a+b;
}//最大公约数函数
ll spid(ll a,ll b,ll p)
{
    ll ans=1;
    while(b)
    {
        if(b&1)ans=ans*a%p;
        b>>=1;
        a=a*a%p;
    }
    return ans;
}//快速幂函数
///泡沫在阳光下闪烁,像星辰在寂静得夜空中闪耀

///秋雨

void solve()
{
    ll n,m,a,b;
    cin>>n>>m>>a>>b;
    if(n>m)swap(n,m);
    if(n==1&&m==2)
    {
        cout<<"Yes\n";
        return;
    }
    if(n*m%2)
    {
        cout<<"No\n";
        return;
    }
    if(a==1&&b==1)
    {
        cout<<"Yes\n";
        return;
    }
    else if(a==0&&b==1)///规则1存在
    {
       if(n==1)
       {
           cout<<"No\n";
           return;
       }
        cout<<"Yes\n";
        return;
    }
    else if(a==1&&b==0)///规则2存在
    {
        if(n==1&&m%2==0)
        {
            cout<<"Yes\n";
            return;
        }
        cout<<"No\n";
        return;
    }
    else///都存在
    {
        if(n==1&&m==2)
        {
            cout<<"Yes\n";
            return;
        }else 
        {
            cout<<"No\n";
        }
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t=1;
    cin>>t;
    while(t--)
    {
        solve();
    }
}
///在秋天邂逅, 在春天发芽,在夏天壮大,在秋天萧瑟,在冬天萎缩,

///而后,春天再度归来。



H:

        题意:给一个无相图(可能有环),给m条边,点上有权值,权值由你自由分配。问从你任意选的一个点开始,每次走这个点与之相连的比这个点权值还小的权值最小的相邻点,问最多能走多少个点。

        解题思路:发现数据范围n是2e5,对于每次取点,就会增加这个点相邻点数量的时间复杂度,所以粗略计算,时间复杂度是40*40*a1*a2*...*ay,这里a1+a2+a3+...+ay=40,大概能过,写一发dfs,就暴力过去了。需要注意的是,每次取点取的是相邻点中,权值最小的点,也就是说,当我们取了其中一个相邻点,那么其他相邻点在之后的过程中就不能取了。也就是说vis数组不能是bool,而应该是记录被打上多少次标记。具体见代码。

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define int long long
#define double long double
#define Int __int128
#define pb push_back
#define N (int)3e5+10
#define MAX_LOG 21
#define ff first
#define ss second
#define M 5005
#define ull unsigned long long
using namespace std;
const double PI=3.1415926535897932385;
const ll LLMAX=9223372036854775807ll;
const ll LLMIN=-9223372036854775808ll;
//const int MAX_INT=0x3f3f3f3f;
const int IIMAX=2147483647;
const int IIMIN=-2147483648;
const int INF=0x3f3f3f3f;
typedef pair<ll,ll> PLL;
ll gcd(ll a,ll b)
{
    if(b) while((a%=b)&&(b%=a));
    return a+b;
}//最大公约数函数
ll spid(ll a,ll b,ll p)
{
    ll ans=1;
    while(b)
    {
        if(b&1)ans=ans*a%p;
        b>>=1;
        a=a*a%p;
    }
    return ans;
}//快速幂函数
///泡沫在阳光下闪烁,像星辰在寂静得夜空中闪耀

///秋雨
unordered_set<ll>st[41];
vector<int>vis(40,0);
ll ans=0;
void dfs(int u,int fa,int cnt)
{
    ans=max(cnt,ans);
    for(auto i:st[u])
    {
        if(vis[i]||fa==i)continue;
        for(auto j:st[u])
            vis[j]++;
        dfs(i,u,cnt+1);
        for(auto j:st[u])
            vis[j]--;
    }
};
void solve()
{
    ll n,m;
    cin>>n>>m;
    for(int i=1; i<=m; i++)
    {
        ll u,v;
        cin>>u>>v;
        st[u].insert(v);
        st[v].insert(u);
    }
    for(int i=1; i<=n; i++)
    {
        vis[i]=1;
        dfs(i,-1,1);
        vis[i]=0;
    }
    cout<<ans<<'\n';
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t=1;
//    cin>>t;
    while(t--)
    {
        solve();
    }
}
///在秋天邂逅, 在春天发芽,在夏天壮大,在秋天萧瑟,在冬天萎缩,

///而后,春天再度归来。



  • 13
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值