【传智杯】初赛部分题解

🍎 博客主页:🌙@披星戴月的贾维斯
🍎 欢迎关注:👍点赞🍃收藏🔥留言
🍇系列专栏:🌙 蓝桥杯
🌙请不要相信胜利就像山坡上的蒲公英一样唾手可得,但是请相信,世界上总有一些美好值得我们全力以赴,哪怕粉身碎骨!🌙
🍉一起加油,去追寻、去成为更好的自己!

提示:以下是本篇文章正文内容,下面案例可供参考


前言

    给大家推荐一个刷题网站:洛谷,提高我们的算法能力的一个重要途径就是刷题,废话不多说,开始!

🍎1.P8825 [传智杯 #3 初赛] 运气

题目背景

YYH Land(Yoauld,Youthful & Happy Land) 是位于炽蓝仙野的一片神奇的国度,那里的人们过着无拘无束的的快乐生活。

题目描述

哈兰·斯威提是 YYH Land 远近闻名的注铅骰子爱好者。有一天他碰到了这么一个问题:
你有一枚 6 个面的骰子,分别写了1, 2, 3, 4, 5, 6, 每一面朝上的概率是均等的。
现在哈兰想知道,如果他投掷 n 次,并且将结果按顺序写在纸上成为一个数。(比如说如果哈兰扔了
3 次,分别是3, 2, 5, 那么他最后得到的数就是325). 他现在想知道这个数是 k 的倍数的可能情况有多少种,其中 k 是一个特定的数。

输入格式

一行两个整数 n,k ,意义如题所示。

输出格式

一行一个整数,表示答案。
输入输出样例

输入 #1         输出

2 11        6

数据规模与约定
对于 40% 的数据,满足 n 分别为 1, 2, 3,4
对于 另外30% 的数据, 满足 1 <= k <= 3
对于 100% 的数据,满足 1<= n <= 10, 1<= k <=1000

分析题意:

在投掷n次骰子中,把每一次骰子掷出的点数组合在一起,求组合的数字对k取模==0的数有多少个,并且对结果对1e9 + 7取模,因为n 最多取到10,所以最大的数为6666666666,会爆int,所以最好要把数据类型定义为long long。并且我们可以根据数据范围 n <= 10来大致判断该题的算法,应该是dfs搜索或者是dp之类的,或者是一些入门题的模拟。

写法1:暴力模拟(过60%)
思路:找出n次掷出骰子的最小值和掷出骰子的最大值作为for循环的判断起始值和结束值。如果符合条件就ans++

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

const int mod = 1e9 + 7;
typedef long long ll;
int n, k;
string s;
ll ans = 0;
bool cheak(ll x)
{
    
    while(x)
    {
        int h = x % 10;
        x /= 10;
        if(h > 6 || h == 0) 
        {
            return false;
        }
    }
    return true;
}
int main ()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> k;
    //直接考虑k的倍数,如果k的倍数出现>6 &&=0的直接pass,还有位数,后面直接输出答案
    ll Max = 6;
    ll Min = 1;
    while(n > 1)
    {
        Max *= 10;
        Max += 6;
        Min *= 10;
        Min += 1;
        n--;
    }
    int f = (Min - 1) / k;
     for(int i = f; (ll)i * k <= Max; i++)
     {
         if( cheak(i * k) && i * k >= Min) ans++;
     }
     ans %= mod;
    cout << ans << endl;
    return 0;
}

在这里插入图片描述
写法2:dfs深搜 写法很简单

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

const int mod = 1e9 + 7;
ll n, k, ans;
void dfs(int u, ll sum) //记得这里的sum要ll,否则会卡
{
    if(u == n) //判断结束条件,次数到n
    {
        if(sum % k == 0) ans++;
        return;
    }
    for(int i = 1; i <= 6; i++) dfs(u + 1, sum + 10 * i);
    //非常简单的dfs
}

int main ()
{
    cin >> n >> k;
    dfs(0, 0); //第一个参数是次数,第二个参数是现在骰子总的结合点数
    
    cout << ans << endl;
    return 0;
}

在这里插入图片描述

🍎2.P8837 [传智杯 #3 决赛] 商店

[传智杯 #3 决赛] 商店

题目背景

disangan333 想给 disangan233 买一个礼物,于是他和你一起逛商店。

题目描述

n n n 名同学去逛商店,店里有 m m m 个物品,第 i i i 人有 w i w_i wi 块钱,第 i i i 个物品价格 c i c_i ci 元。

每个人至多买一个物品,每个物品只能被买一次,问最多有多少人能买到物品。

对于所有数据,

评论 28
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

披星戴月的贾维斯

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值