蓝桥冲刺31天打卡—Day17

这篇博客探讨了四个编程题目:计算字符串内部距离的简单模拟,扩散问题的多源BFS解决,错误票据的断号与重号查找,以及寻找最大和为倍数的三数之和问题。文章详细解析了思路并提供了代码实现,适合提升编程思维和算法能力。

目录

1.🌟距离和

📕题目描述:

☀️思路:

✏️代码 : 

2.🌟扩散

📕题目描述:

☀️思路:

✏️代码 : 

3.🌟错误票据

📕题目描述:

☀️思路:

✏️代码 : 

4、🌟倍数问题

📕题目描述:

☀️思路

 ✏️暴力代码 : (能骗60%的分数)

✏️未通过dp代码


1.🌟距离和

📕题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

两个字母之间的距离定义为它们在字母表中位置的距离。例如 A 和 C 的距离为 2,L 和 Q 的距离为 5。

对于一个字符串,我们称字符串中两两字符之间的距离之和为字符串的内部距离。

例如:ZOO 的内部距离为 22,其中 Z 和 O 的距离为 11。

请问,LANQIAO 的内部距离是多少?

☀️思路:

简单模拟题

✏️代码 : 

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
string s="LANQIAO";
//abcdefghijklmnopqrstuwxyz
int sum;
int main(){
	for(int i=0;i<s.size()-1;i++){
		for(int j=i+1;j<s.size();j++){
			if(s[i]>s[j]){
				sum+=s[i]-s[j];
			}else{
				sum+=s[j]-s[i];
			}
		}
	}
	cout<<sum;
	return 0;
}//162

2.🌟扩散

📕题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

小蓝在一张无限大的特殊画布上作画。

这张画布可以看成一个方格图,每个格子可以用一个二维的整数坐标表示。

小蓝在画布上首先点了一下几个点:(0, 0), (2020, 11), (11, 14), (2000, 2000)

只有这几个格子上有黑色,其它位置都是白色的。

每过一分钟,黑色就会扩散一点。具体的,如果一个格子里面是黑色,它就会扩散到上、下、左、右四个相邻的格子中,使得这四个格子也变成黑色(如果原来就是黑色,则还是黑色)。

请问,经过 2020 分钟后,画布上有多少个格子是黑色的

☀️思路:

多源bfs。将几个点全部入队,使用d数组来记录时间(步长),每走过一个点,vis数组标记为true,最后记录所有vis数组为true的数量。注意:坐标点有负数情况,所以先提前处理好,将所有点横纵坐标+3000

✏️代码 : 

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include<queue>
using namespace std;
const int N=10000;
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
bool vis[N][N];
int d[N][N];//步数即时间
struct Node{
	int x;
	int y;
};
void bfs(){
	queue<Node>q;
	memset(vis,false,sizeof(vis));
	memset(d,-1,sizeof(d));
	q.push({3000, 3000}); d[3000][3000] = 0;
	q.push({5020, 3011}); d[5020][3011] = 0;
	q.push({3011, 3014}); d[3011][3014] = 0;
	q.push({5000, 5000}); d[5000][5000] = 0;
	
	vis[3000][3000] = 1;vis[5020][3011]= 1;
	vis[3011][3014] = 1;vis[5000][5000] = 1;
	
	
		while(q.size()){
			Node t=q.front();
			q.pop();
			
			if(d[t.x][t.y]==2020) return;//时间到达2020 结束
		
			for(int i=0;i<4;i++){
				int fx=t.x+dx[i],fy=t.y+dy[i];
				if(fx<0||fx>10000||fy<0||fy>10000) continue;
				
				if(vis[fx][fy]) continue;
				if(d[fx][fy]!=-1) continue;
				
				q.push({fx,fy});
				vis[fx][fy]=1;
				d[fx][fy]=d[t.x][t.y]+1;//时间加一
			}
		}
	
}
int main(){
	bfs();
	int ans=0;//别忘了初值设0
	for(int i=0;i<10000;i++){
		for(int j=0;j<10000;j++){
			if(vis[i][j]) ans++;
		}
	}
	cout<<ans;
	return 0;
}//20312088

3.🌟错误票据

📕题目描述


某涉密单位下发了某种票据,并要在年终全部收回。
每张票据有唯一的ID号。全年所有票据的ID号是连续的,但ID的开始数码是随机选定的。
因为工作人员疏忽,在录入ID号的时候发生了一处错误,造成了某个ID断号,另外一个ID重号。
你的任务是通过编程,找出断号的ID和重号的ID。
假设断号不可能发生在最大和最小号。

输入格式

要求程序首先输入一个整数N(N<100)表示后面数据行数。
接着读入N行数据。
每行数据长度不等,是用空格分开的若干个(不大于100个)正整数(不大于100000),请注意行内和行末可能有多余的空格,你的程序需要能处理这些空格。
每个整数代表一个ID号。

输出格式

要求程序输出1行,含两个整数m n,用空格分隔。
其中,m表示断号ID,n表示重号ID
 

输入:

2
5 6 8 11 9 
10 12 9
 

输出

7 9

☀️思路:

一开始在dev里跑不出结果,在蓝桥云课评测里能通过,后来问了大佬,要用ctrl+d或者在末尾输eof来结束输入,才能成功输出答案。

题目本身没有什么难度,就把输入的所有数放入a数组,再对a进行递增排序,遍历a中所有数,

a[i]==a[i+1]为重号,a[i]+1!=a[i+1]为断号

✏️代码 : 

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1e5+10 ;
int n;
int a[N];
int x,y;
int i,j;
string s;
int main(){
	cin>>n;
	while(cin>>a[i]){
		i++;
	}
	sort(a,a+i);
	for( j=0;j<i-1;j++){
		if(x!=0&&y!=0) break;
		if(a[j]==a[j+1]){
			x=a[j];//重号
		}else if(a[j]+1!=a[j+1]){
			y=a[j]+1;//断号
		}
	}
	cout<<y<<" "<<x;
	return 0;
}//编译器里要用ctrl+d结束程序运行才能输出
//或者加eof

4、🌟倍数问题

📕题目描述

众所周知,小葱同学擅长计算,尤其擅长计算一个数是否是另外一个数的倍数。但小葱只擅长两个数的情况,当有很多个数之后就会比较苦恼。现在小葱给了你 n 个数,希望你从这 n 个数中找到三个数,使得这三个数的和是 K 的倍数,且这个和最大。数据保证一定有解。

输入描述

第一行包括 2 个正整数 n, Kn, K。

第二行 n 个正整数,代表给定的 n 个数。

其中,,,给定的n个数不超过

输出描述

输出一行一个整数代表所求的和。

输入

4 3

1 2 3 4

输出

9

☀️思路

三维01背包加取模优化(不会优化)

闫氏dp分析法

状态表示:f(i,j,k)    

  • 集合:从所有前i个数中选且已经选了j个数且总和模k的余数是k的选择的集合
  • 属性:Max

状态计算:选与不选第i个物品

  • 选择第i个物品:f(i-1,j-1,k-a[i]%k)
  • 不选择第i个物品:f(i-1,j,k)

为了防止负数取模出现错误的情况,所以对x取模记为 x mod k + k

(普通的dp做法WA了,不会优化)😢

 ✏️暴力代码 : (能骗60%的分数)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1e5+10 ;
typedef long long ll;
ll a[N];
int n,m;
ll ans=0;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++){
		scanf("%lld",&a[i]);
	}
	for(int i=0;i<n;i++){
		for(int j=0;j<n&&i!=j;j++){
			for(int k=0;k<n&&j!=k&&i!=k;k++){
				ll sum=a[i]+a[j]+a[k];
				if(sum>ans&&sum%m==0){
					ans=sum;
				}
			}
		}
	}
	printf("%lld",ans);
	return 0;
}

✏️未通过dp代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+10, M=1010;

int n, m;
int a[N];
int f[N][5][M];

int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) scanf("%d", &a[i]);

    memset(f, -0x3f, sizeof f);
    for(int i=0;i<=n;i++) f[i][0][0]=0;

    for(int i=1;i<=n;i++)
        for(int j=1;j<=3;j++)
            for(int k=0;k<m;k++)
                f[i][j][k]=max(f[i-1][j][k], f[i-1][j-1][((k-a[i])%m+m)%m]+a[i]);

    int ans=-1;
    for(int i=1;i<=n;i++) ans=max(ans, f[i][3][0]);
    cout<<ans<<endl;
}

### 获取蓝桥等考C++组别17级历年真题的途径 蓝桥等考C++组别17级的历年真题是备考过程中不可或缺的资源,通过练习真题可以更好地理解考试难度、题型分布以及常见解题思路。虽然官方并未公开大规模的真题下载渠道,但可以通过以下方式获取相关资源: - **蓝桥杯官网**:蓝桥杯竞赛官网提供了部分往届真题和样题,例如“特别数的和”等编程大题可以在官网或其配套练习平台中找到[^1]。建议注册账号并参与其在线训练营或模拟赛,以获取更多练习机会。 - **牛客网(NowCoder)**:牛客网设有蓝桥杯专题板块,其中包含了历届真题的重现与在线练习功能,支持C++语言提交并提供详细的题解和测试用例反馈。 - **蓝桥杯官方出版物**:蓝桥杯组委会曾出版过《蓝桥杯竞赛真题解析》系列书籍,其中涵盖了包括17级在内的多个组别的真题与详解,可通过正规图书平台购买[^1]。 - **GitHub与技术博客**:一些参赛选手或教练会在GitHub上分享历年真题的解题代码和思路分析,例如搜索“lanqiao 17级 真题”可以找到开源项目和题解资源。 - **培训机构与高校资源**:部分高校或编程培训机构会整理蓝桥杯历年真题作为教学资料,若为在校学生,可向指导老师或课程助教咨询是否有相关资源可供下载。 ### 示例代码:特别数的和(编程大题) 以下是一个典型的蓝桥杯编程大题“特别数的和”的C++实现: ```cpp #include <iostream> #include <string> using namespace std; bool contains(string s, char c) { return s.find(c) != string::npos; } int main() { long long n; cin >> n; long long sum = 0; for (long long i = 1; i <= n; ++i) { string num = to_string(i); if (contains(num, '2') || contains(num, '0') || contains(num, '1') || contains(num, '9')) { sum += i; } } cout << sum << endl; return 0; } ``` 该题要求统计1到n中包含数字2、0、1、9的自然数的总和,适用于蓝桥杯C++组别中等难度的编程大题练习。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

月色美兮

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

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

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

打赏作者

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

抵扣说明:

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

余额充值