牛客周赛 Round 30(题解A-D)

【链接】:https://ac.nowcoder.com/acm/contest/73760

比赛时间:2024-01-28    19:00-21:00

赛制:IOI 

前提:本人真的是小白,题解也只是为了自己的复盘,E、F由于这两题知识点(dp)还没学习到,所以现在无法对其进行补题。

目录

A.小红的删字符

B.小红的正整数

C.小红的构造回文

D.小红整数操作

E.小红树上染色

F.小红叒战小紫

A.小红的删字符

知识点:语法

难度:200

思路:俗称“签到题”,直接输出字符串第一个和最后一个字符即可

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s;cin>>s;
    s.erase(1,1);
    cout<<s;
    return 0;
}

复盘:比赛时未想到最优解,运用erase函数有点想太多了

重新写了一个更符合思路的代码

直播讲解的思路:签到题。直接输出第一个字符和最后一个字符即可

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s;cin>>s;
    cout<<s[0]<<s[2];
    return 0;
}

B.小红的正整数

知识点:贪心,排序

难度:500

思路:先排序,再考虑第一位是否为0,如果是就向后挪

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N];
int main()
{
    int n;cin>>n;
    int i=0;
    while(n>0)
    {
        a[i]=n%10;
        n/=10;
        i++;
    }
    sort(a,a+i);
    if(a[0]==0)
    {
        int idx=0;
        for(int j=0;j<i-1;j++)
        {
            if(a[j]==0&&a[j+1]!=0)
            {
                idx=j;
                break;
            }
        }
        int temp=a[idx+1];
        for(int j=idx;j>=0;j--)
        {
            a[j+1]=a[j];
        }
        a[0]=temp;
    }
    for(int j=0;j<i;j++)
        cout<<a[j];
    return 0;
}

复盘:比赛时的思路过于乱了,且代码量有点大

重新写了一个更精简点的代码

直播讲解的思路:首先将最小数位的非零移动到首位,剩下的数位从小到大输出即可

另外本题数据范围较小,也可以暴力从小到大枚举,check是否符合重排标准

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s;cin>>s;
    sort(s.begin(),s.end());
    if(s[0]=='0') 
    {
        for(int i=1;i<s.size();i++) 
        {
            if(s[i]!='0')
            {
                swap(s[0],s[i]);
                break ; 
            }
        }
    }
    cout<<s;
    return 0;
}

C.小红的构造回文

知识点:枚举

难度:900

思路:由于给的字符串就是回文,你可以直接将前半部分与后半部分进行交换,然后将交换完后的字符串与最初进行比较,判断是否相同

#include<bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    string s;cin>>s;
    string s1,s2,str;
    int len=s.size();
    s1=s.substr(0,len/2);
    if(len%2==0)
    {
        s2=s.substr(len/2,len/2);
        str=s2+s1;
    }
    else 
    {
        s2=s.substr(len/2+1,len/2);
        str=s2+s[len/2]+s1;
    }
    if(str==s)cout<<-1;
    else cout<<str;
    return 0;
}

复盘:我这个思路就是需要求字符串的长度奇还是偶,要进行灵活变动

直播讲解的思路:由于给定的是回文串,我们直接枚举前半部分,找到任意一个相邻不同的位置,交换这两个字符即可(需要在对称的位置也做一次交换操作)

D.小红整数操作

知识点:数学/二分

难度:1400

思路:先求最大公约数,将x,y互质,再进行模拟,求解

比赛时,由于IOI赛制,就输出1,骗到15分

#include <bits/stdc++.h>
using namespace std ;
#define int long long
int gcd(int a,int b)
{
    return b?gcd(b,a%b):a; 
}
signed main()
{
    int x,y,l,r; 
    cin>>x>>y>>l>>r; 
    int k=gcd(x,y); 
    x/=k,y/=k;
    if(x==1)
    {
        return cout<<max((r-l*y)/y+1,1LL*0),0;
    }
    int ret=0; 
    for(int c=1;x*c<=r&&y*c<=r;c++)
    {
        if(x*c>=l&&y*c>=l)ret++; 
    }
    cout<<ret; 
    return 0 ; 
}

直播讲解的思路:首先可以将x和y的所有公因数除掉,形成x和y互素的情况,接下来就只需要考虑乘法了

E.小红树上染色

知识点:树形dp

难度:1700

直播讲解的思路:我们定义dp[i][0/1]代表i号节点不染色/染色的子树合法方案数,dfs中使用后序遍历,当子树所有信息都被求出来了以后,我们根据当前节点的颜色讨论不同情况的合法方案转移即可。

F.小红叒战小紫

知识点:期望dp

难度:2200

比赛时,由于IOI赛制,就输出0,骗到11.67分

直播讲解的思路:我们定义dp[i][j]为:小红剩余恰好j个1血量怪物时,需要进行的回合数。一共有4种情况:两个人都抽到1(无事发生,转移到dp[i][j]),两个人都抽到2(无事发生,转移到dp[i][j]),小红抽到1小紫抽到2(转移到dp[i-1][j]),小红抽到2小紫抽到1(转移到dp[i][j-1]),我们列方程后即可推出转移方程:

dp[i][j]=(1-p2-p3)*dp[i][j]+p2*dp[i-1][j]+p3*dp[i][j-1]+1

(p2+p3)*dp[i][j]=p2*dp[i-1][j]+p3*dp[i][j-1]+1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

July.19th

感谢各位对我的支持

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

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

打赏作者

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

抵扣说明:

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

余额充值