【蓝桥杯】枚举1

今天是【蓝桥杯】枚举的6道练习题。

一、门牌制作

题目描述
门牌制作20
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
小蓝要为一条街的住户制作门牌号。
这条街一共有 2020 位住户,门牌号从 1 到 2020 编号。
小蓝制作门牌的方法是先制作 00 到 99 这几个数字字符,最后根据需要将字符粘贴到门牌上,例如门牌 1017 需要依次粘贴字符 1、0、1、7,即需要 1 个字符 0,2 个字符 1,1 个字符 7。
请问要制作所有的 1 到 2020 号门牌,总共需要多少个字符 2?

我在写这道题的时候,没有写13行。14行写的是while(i),内层循环i值的更新改变了外层循环i的值,进入了死循环。要注意这一点。

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

typedef long long LL;

int main(void)
{
	int cnt = 0;
	int res;
	for(int i = 2; i <= 2020; i++)
	{
		int n = i;  //注意这里
		while(n)
		{
			res = n % 10;
			if(res == 2)
				cnt++;
			n /= 10;
		}	
	}	
	cout<< cnt << endl;
	return 0;
}

二、顺子日期

顺子日期21
问题描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
小明特别喜欢顺子。顺子指的就是连续的三个数字:123、456 等。顺子日期指的就是在日期的 yyyymmdd 表示法中,存在任意连续的三位数是一个顺子的日期。例如 20220123 就是一个顺子日期,因为它出现了一个顺子:123; 而 20221023 则不是一个顺子日期,它一个顺子也没有。小明想知道在整个 2022 年份中,一共有多少个顺子日期?
法一:直接手推。分别是,0120~0129共十个,1012,1123,1230,1231。
法二:枚举。
更新中……

三、货物摆放

货物摆放22
题目描述
小蓝有一个超大的仓库,可以摆放很多货物。
现在,小蓝有 n 箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、宽、高。
小蓝希望所有的货物最终摆成一个大的长方体。即在长、宽、高的方向上分别堆 L、W、H 的货物,满足 n = L×W×H。
给定 n,请问有多少种堆放货物的方案满足要求。
例如,当 n = 4 时,有以下 6 种方案:1×1×4、1×2×2、1×4×1、2×1×2、2 × 2 × 1、4 × 1 × 1。
请问,当 n = 2021041820210418(注意有 16位数字)时,总共有多少种方案?
提示:建议使用计算机编程解决问题。
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

中间输出pos发现2021041820210418只有128个因子。因此const int N = 1e3+10;就足够了。平时遇到的数,它们的因子数也没有很多。你看,2021041820210418这么大的数因子也才只有128个嘛~

#include<iostream>
using namespace std;

typedef long long LL;
const int N = 1e3+10;
LL yinzi[N];

int main(void)
{
	int pos = 0;
	LL n = 2021041820210418;
	for(LL i = 1; i*i <= n; i++) //
		if(n % i == 0)
		{
			yinzi[pos++] = i;
			if(i != n/i)
				yinzi[pos++] = n/i;
		}	
	
	LL ans = 0;		
	for(LL j = 0; j < pos; j++ )
	{
		for(LL k = 0; k < pos; k++)
		{
			if(yinzi[j] * yinzi[k] > n)  continue;
			
			for(LL l = 0; l < pos; l++)
			{
				if(yinzi[j] * yinzi[k] * yinzi[l] == n)
					ans++;
			}
		}
	}
	cout<< ans << endl;
	return 0;
}

四、质数

质数23
题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
我们知道第一个质数是 2、第二个质数是 3、第三个质数是 5……
请你计算第 2019个质数是多少?

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

typedef long long LL;

bool is_prime(int x)  //写一个判断质数的函数
{
	for(int i = 2; i <= x/2; i++)
		if(x % i == 0)
			return false;
	return true;
}

int main(void)
{
	int cnt = 0,res;  //cnt计有几个质数,res是一个临时变量。 
	int i = 2;
	while(cnt != 2019)
	{
		if(is_prime(i))
			cnt++;
		res = i++;
	}
	cout<< res << endl;
	return 0;
}

五、数的分解

数的分解24
题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
把 2019 分解成 3 个各不相同的正整数之和,并且要求每个正整数都不包含数字 2 和 4,一共有多少种不同的分解方法?
注意交换 3 个整数的顺序被视为同一种方法,例如1000+1001+18和1001+1000+18 被视为同一种。

#include<iostream>
using namespace std;

bool check(int x)  //检验一个数的各位有没有2,4 
{
	int c;
	while(x)
	{
		c = x%10;
		if(c == 2 || c == 4)
			return true; //如果有2,4返回1 
		x /= 10;
	}
	return false;
}

int main(void)
{
	int cnt = 0;
	for(int i = 1; i <= 673; i++)  // i <= 2019也行 
	{
		for(int j = i+1; j <= (2019-i)/2; j++)  // j <= 2019也行 
		{	
				if(i >= j || i >= 2019-i-j || j >= 2019-i-j)  continue;
				int res = check(i) + check(j) + check(2019-i-j);
				
				if(res == 0)
					cnt++;
		}
	}
	cout<< cnt << endl; 
	return 0;
}

六、赢球票

赢球票25
题目描述
某机构举办球票大奖赛。获奖选手有机会赢得若干张球票。
主持人拿出 N 张卡片(上面写着1⋯N 的数字),打乱顺序,排成一个圆圈。你可以从任意一张卡片开始顺时针数数: 1,2,3 ⋯如果数到的数字刚好和卡片上的数字相同,则把该卡片收入囊中,从下一个卡片重新数数。直到再无法收获任何卡片,游戏结束。囊中卡片数字的和就是赢得球票的张数。
比如:卡片排列是:1 2 3。
我们从 1 号卡开始数,就把 1 号卡拿走。再从 2 号卡开始,但数的数字无法与卡片对上,很快数字越来越大,不可能再拿走卡片了。因此这次我们只赢得了 1 张球票。
还不算太坏!如果我们开始就傻傻地从 2 或 3 号卡片数起,那就一张卡片都拿不到了。
如果运气好,卡片排列是 2 1 3,那我们可以顺利拿到所有的卡片!
本题的目标:已知顺时针卡片序列,随便你从哪里开始数,求最多能赢多少张球票(就是收入囊中的卡片数字之和)
输入描述
第一行一个整数 N(N≤100),表示卡片数目。
第二行N 个整数,表示顺时针排列的卡片。
输出描述
输出一行,一个整数,表示最好情况下能赢得多少张球票。

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1e2 + 10;

int n;
int a[N], backup[N];

int get(int k)
{
    memcpy(a, backup, sizeof a);
    
    int sum = 0, len = 1;
    while (true)
    {
        while (a[k] == 0)
            k = (k + 1) % n;
        if (a[k] == len)
        {
            sum += a[k];
            a[k] = 0;
            len = 1;
            if (*max_element(a, a + n) == 0)
                return sum;
        }
        else
            len ++;
        k = (k + 1) % n;
        if (len > n)
            return sum;
    }
}

int main()
{
    cin >> n;
    for (int i = 0; i < n; i ++ )
        cin >> backup[i];
    
    int res = 0;
    for (int i = 0; i < n; i ++ )
        res = max(res, get(i));
    
    cout << res << endl;
    
    return 0;
}

持续更新,欢迎一起学习~

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
蓝桥杯中常用的枚法有两种:排列型枚和组合型枚。其中,排列型枚是指从n个元素中取m个元素进行排列,而组合型枚是指从n个元素中取m个元素进行组合。下面以一个例子来介绍排列型枚的实现方法。 假设有n个元素,需要从中选出m个元素进行排列,可以使用递归的方式实现。具体实现方法如下: ```python import numpy as np chosen = [] # 存储已选元素 n = 0 # 元素总数 m = 0 # 需要选出的元素个数 def calc(x): """ 递归函数,从第x个元素开始选取 """ if len(chosen) > m: # 已选元素个数超过m个,返回 return if len(chosen) + n - x + 1 < m: # 剩余元素个数不足m个,返回 return if x == n + 1: # 已经选完n个元素,输出结果 for i in chosen: print(i, end=' ') print(' ') return chosen.append(x) # 选取第x个元素 calc(x + 1) # 递归选取下一个元素 chosen.pop() # 不选第x个元素 calc(x + 1) # 递归选取下一个元素 if __name__ == '__main__': tem = input().split() n = int(tem[0]) m = int(tem[1]) calc(1) # 从第1个元素开始选取 ``` 以上代码实现了从n个元素中选取m个元素进行排列的功能,其中chosen列表存储已选元素,calc函数为递归函数,从第x个元素开始选取,如果已选元素个数超过m个或剩余元素个数不足m个,则返回;如果已经选完n个元素,则输出结果;否则,选取第x个元素或不选第x个元素,递归选取下一个元素。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

qing小星星

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

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

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

打赏作者

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

抵扣说明:

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

余额充值