C++牛客小白月赛题目分享(1)生不逢七,交换数字,幻兽帕鲁

目录

1.前言

2.三道题目

1.生不逢七

1.题目描述

2.输入描述:

3.输出描述:

4.示例:

5.题解:

2.交换数字

1.题目描述:

2.输入描述:

​编辑 

3.输出描述:

4.示例:

5.题解:

3.幻兽帕鲁

1.题目描述:

2.输入描述:

3.输出描述:

4.示例:

5.题解:

3.小结



1.前言

今天小蒟蒻为大家分享牛客小白月赛93部分题目的题解,考了蛮多高精度滴~,一共三道题,希望你能对大家有所帮助~

2.三道题目

1.生不逢七

1.题目描述

睡前游戏中最简单又最好玩的游戏就是这个啦!

该游戏规则为:多名玩家轮流报数,当要报的数字中含有 7或者是 7 的倍数时(例如 37,49),不能将该数报出来,要换一种提前规定好的方式报数,当一个人报错或者报慢了这个人就输了。我们认为玩家是围成一圈进行游戏的,第 n 个人报完数之后,会轮到第 1 个人报数。


现在告诉你玩家的总人数以及你上一个人报的数(用数字表示,即便这个数含有 7 或者是 7 的倍数),你需要预测接下来 k 轮你要报的数字,当你需要报的数字含有 7 或者是 7 的倍数时,你需要输出字符 p。

2.输入描述:

 

3.输出描述:

 

4.示例:

5.题解:

#include<iostream>
#include<algorithm>
using namespace std;

int t=0;
int n=0,a=0,k=0;

int func2(int y1){
     if(y1%7==0)return 0;
     while(y1){
         if(y1%10==7)return 0;
         y1=y1/10;
     }
    return 1;
}

void func1(int x,int y,int z){
     while(z--){
         int flag=func2(y);
         if(flag==0)printf("p ");
         else printf("%d ",y);
         y=y+x;
     }
}

int main(){
	scanf("%d",&t);
    while(t--){
        scanf("%d %d %d",&n,&a,&k);
        func1(n,a+1,k);
        printf("\n");
    }
	return 0;
} 

这道题作为签到题,比平时的只需要几个语句的就可以输出的要难上一点,但也是单纯的模拟,只是本人写的代码需要优化的仍有很多,所以显得很长。

这道题整体思路如下:先按照题意中的报号顺序推出自己每一次的号(第一次的号只需要+1,后面的号码1需要加上组内总人数),再判断是否可以%7或者是否含7即可,最后输出。

2.交换数字

1.题目描述:

2.输入描述:

3.输出描述:

4.示例:

5.题解:

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;

char a[200005],b[200005];
int n;
long long sum1=0,sum2=0;

int main(){
    scanf("%d%s%s",&n,&a,&b);
    for(int i=0;i<n;i++){
       if(a[i]>b[i])swap(a[i],b[i]);
    }
    for(int j=0;j<n;j++){
       sum1=sum1*10+(a[j]-'0');
        sum1=sum1%998244353;
       sum2=sum2*10+(b[j]-'0');
        sum2=sum2%998244353;
    }
    printf("%d\n",sum1*sum2%998244353);
    return 0;
}
  • 这道题有一个简单的数学问题:a*b何时最小。可以比较容易得出来的是,当a和b分别满足题目条件的最大和最小的时候相乘,该值为最小(可以举个简单的例子,若当下有1,2,3,4,5,6这6个数,显然123*456最小,找不到比这个还小的了)。
  • 解决了这个问题以后,让我们看一下这个题的限制条件,n可以取到200000,那么这个数最大可以取到10的200000次方,这显然开long long也无法解决(64位中long long最大为2的64次方),于是我们用字符串数组来存储这么一个巨大的数字。
  • 接着运用swap函数将a和b每一位的较大和较小至于一侧,最后相乘%998244353即可(求a和b的值时也要%998244353,防止溢出,也不会影响结果)。

3.幻兽帕鲁

1.题目描述:

2.输入描述:

3.输出描述:

4.示例:

5.题解:

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

void solve()
{
    int n , m;
    cin >> n >> m;
    while (m -- )
    {
        long long x , y = 0;
        cin >> x;
        for (int i = 0 ; i < n ; i ++ )
        {
            y <<= 1;
            y = y | (x & 1);
            x >>= 1;
        }
        cout << y << endl;
    }
}

int main()
{
    solve();
    return 0;
}

 这道题的思路我是参考着其他大佬的思路才做出来的,正所谓代码量与思考量成反比,虽然上面只有寥寥数行代码,但思路很有价值,当你明白后绝对会自己有巨大提升。我也是跟着代码模拟了几遍才明白其原理,利用了最最基本的左移右移操作符以及按位与按位或操作实现了先打印偶数,再打印奇数。(这道题不能按照平常思路来做,因为n可以取到60,即2的60次方-1,开数组绝对开不了这么大)

接下来就以第一个示例为主,我一步一步带着大家模拟:

  • 输入2,4表示一共有4只帕鲁,需输出四行
  • 进入solve函数中

x先输入0,进入循环

  • y左移一位还为0
  • 0按位与1仍为0,与y按位或还为0,y仍为0
  • x右移一位仍为0
  • 接下来n次循环y值不变,则输出y为0

x输入1,进入循环

  • y左移一位还为0
  • 1按位与1为1,与y按位或还为1,y为1
  • x右移一位为0
  • 进入第二次循环,y左移一位为2(二进制为01变为010)
  • 最后输出2

x输入2,进入循环

  • y左移一位还为0
  • 2按位与1为0(10和01),与y按位或还为0,y仍为0
  • x右移一位为1
  • 进入第二次循环,y左移一位为0
  • 1按位与1为1,与y按位或还为1,y为1
  • 最后输出1

x输入3,进入循环

  • y左移一位还为0
  • 3按位与1为1,与y按位或为1,y为1
  • x右移一位为1
  • 进入第二次循环,y左移一位为2
  • 1按位与1为1,与y按位或还为3(10与01按位或11),y为3
  • 最后输出3,符合题意

结果真的很奇妙吧!!!大家在下面思考过后也尝试实现一下吧

3.小结

今天分享的三道题到这里就结束了喔了,希望大家有所收获并多多支持哦~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱吃烤鸡翅的酸菜鱼

希望大家对我多多支持喔~

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

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

打赏作者

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

抵扣说明:

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

余额充值