备战蓝桥杯 刷题笔记(第四期)

本文包含一系列编程问题,涉及数字排列以求最小值、识别坏键、计算特定组合数字的和、统计特定分数的学生人数、判断管道施工可行性、找出序列中的特定子序列、寻找朋友数、解决数字金字塔最大和路径及数列分割问题,以及优化牛奶采购策略以降低成本。
摘要由CSDN通过智能技术生成

1,题目描述

给定数字 0-9 各若干个。你可以以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小(注意 0 不能做首位)。例如:给定两个 0,两个 1,三个 5,一个 8,我们得到的最小的数就是 10015558。

现给定数字,请编写程序输出能够组成的最小的数。

输入格式:

输入在一行中给出 10 个非负整数,顺序表示我们拥有数字 0、数字 1、……数字 9 的个数。整数间用一个空格分隔。10 个数字的总个数不超过 50,且至少拥有 1 个非 0 的数字。

输出格式:

在一行中输出能够组成的最小的数。

输入样例:

2 2 0 0 0 3 0 0 1 0
 

输出样例:

10015558

#include<iostream>
using namespace std;
int arr[55];
int main()
{
	//根据输入创建数组 
	int n=0,j; //n为数组长度 
	for(int i=0;i<10;i++)
	{
		cin>>j;//1到10 各数字的数量 
		//全部转移至arr数组中 
		while(j--)
			arr[n++]=i;
	}
	
	for(int i=0;i<n;i++)
	{
		//遍历寻找第一个不为0的数字 
		if(arr[i]!=0)
		{
			cout<<arr[i];//找到第一位并输出 
			//找到的位置开始 数组整体向前移动一位 
			for(int x=i;x<n;x++) 
				arr[x]=arr[x+1];
			break;
		}
	}
	//输出第一位后面的所有数字 
	for(int i=0;i<n-1;i++)
		cout<<arr[i];
} 

 2,题目描述

旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现。现在给出应该输入的一段文字、以及实际被输入的文字,请你列出肯定坏掉的那些键。

输入格式:

输入在 2 行中分别给出应该输入的文字、以及实际被输入的文字。每段文字是不超过 80 个字符的串,由字母 A-Z(包括大、小写)、数字 0-9、以及下划线 _(代表空格)组成。题目保证 2 个字符串均非空。

输出格式:

按照发现顺序,在一行中输出坏掉的键。其中英文字母只输出大写,每个坏键只输出一次。题目保证至少有 1 个坏键。

输入样例:

7_This_is_a_test
_hs_s_a_es
输出样例:

7TI

#include<iostream>
using namespace std;
string s1,s2;
char ans[85];
int n;//答案数组的长度 
int main()
{
	cin>>s1>>s2;
	for(int i=0;i<s1.length();i++)
		for(int j=0;j<s2.length();j++)
		{
			//小写字母改成大写 
			if(s1[i]>=97)
				s1[i]-=32;
			if(s2[j]>=97)
				s2[j]-=32;
			
			//s1和s2中都出现的字母 键盘没坏 
			if(s1[i]==s2[j])
				break;
			//s1中出现 s2中没有 键盘坏了 
			if(j==s2.length()-1)
			{
				if(n==0)//ans数组为空 
				{
					ans[n++]=s1[i]; 
					break;
				}
				for(int k=0;k<n;k++)
				{
					//检查ans数组是否已经记录过 
					if(ans[k]==s1[i])
						break;
					if(k==n-1)//未记录 
						ans[n++]=s1[i]; 
				}
			}
		}
		
	for(int i=0;i<n;i++)
		cout<<ans[i];//输出 
} 

3,题目描述

给定 N 个非 0 的个位数字,用其中任意 2 个数字都可以组合成 1 个 2 位的数字。要求所有可能组合出来的 2 位数字的和。例如给定 2、5、8,则可以组合出:25、28、52、58、82、85,它们的和为330。

输入格式:

输入在一行中先给出 N(1 < N < 10),随后给出 N 个不同的非 0 个位数字。数字间以空格分隔。

输出格式:

输出所有可能组合出来的2位数字的和。

输入样例:

3 2 8 5

输出样例:
330

#include<iostream>
using namespace std;
int n,arr[10],ans[100],sum;
void fun(int i,int j)
{
	//两个数位可以组合出两个的数 
	//分别记录在ans数组 可以避免重复 
	ans[i*10+j]=i*10+j;
	ans[i+j*10]=i+j*10;
}
int main()
{
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>arr[i];//记录输入的各个数 
		
	for(int i=0;i<n-1;i++)
		for(int j=i+1;j<n;j++)
			fun(arr[i],arr[j]);//两两组合 
			
	for(int i=0;i<100;i++)
		sum+=ans[i];//求和 
	cout<<sum;
}

4,题目描述

本题要求读入 N 名学生的成绩,将获得某一给定分数的学生人数输出。

输入格式:

输入在第 1 行给出不超过 105 的正整数 N,即学生总人数。随后一行给出 N 名学生的百分制整数成绩,中间以空格分隔。最后一行给出要查询的分数个数 K(不超过 N 的正整数),随后是 K 个分数,中间以空格分隔。

输出格式:

在一行中按查询顺序给出得分等于指定分数的学生人数,中间以空格分隔,但行末不得有多余空格。

输入样例

10
60 75 90 55 75 99 82 90 75 50
3 75 90 88
输出样例:

3 2 0

#include<iostream>
using namespace std;
int fenshu[105];//存放一到一百的分数 出现的次数 
int main()
{
	int n,t;
	cin>>n;	
	for(int i=0;i<n;i++)
	{
		cin>>t;
		fenshu[t]++;//出现的次数加一 
	}
	int k;
	cin>>k;
	for(int i=0;i<k;i++)
	{
		cin>>t;
		if(i==k-1)//最后一位不用输出空格 
			cout<<fenshu[t];
		else
			cout<<fenshu[t]<<" ";
	}
} 

5,题目描述 

要将一条直径至少为 1 个单位的长管道水平送入地形复杂的岩洞中,究竟是否可能?下面的两幅图分别给出了岩洞的剖面图,深蓝色的折线勾勒出岩洞顶部和底部的轮廓。图 1 是有可能的,绿色部分显示直径为 1 的管道可以送入。图 2 就不可能,除非把顶部或底部的突出部分削掉 1 个单位的高度。

94b84fba13bfb8bb2015261234496e6c.jpeg

本题就请你编写程序,判断给定的岩洞中是否可以施工。

输入格式:

输入在第一行给出一个不超过 100 的正整数 N,即横向采样的点数。随后两行数据,从左到右顺次给出采样点的纵坐标:第 1 行是岩洞顶部的采样点,第 2 行是岩洞底部的采样点。这里假设坐标原点在左下角,每个纵坐标为不超过 1000 的非负整数。同行数字间以空格分隔。

题目保证输入数据是合理的,即岩洞底部的轮廓线不会与顶部轮廓线交叉。

输出格式:

如果可以直接施工,则在一行中输出 Yes 和可以送入的管道的最大直径;如果不行,则输出 No 和至少需要削掉的高度。答案和数字间以 1 个空格分隔。

输入样例1:

11
7 6 5 5 6 5 4 5 5 4 4
3 2 2 2 2 3 3 2 1 2 3
输出样例 1: 

Yes 1
 

输入样例2:

11
7 6 5 5 6 5 4 5 5 4 4
3 2 2 2 3 4 3 2 1 2 3

输出样例2:

No 1

#include<iostream>
#include<math.h>
using namespace std;
int n,arr[2][105];
int main()
{
	cin>>n;
	for(int i=0;i<2;i++)
		for(int j=0;j<n;j++)
			cin>>arr[i][j];
			
	int maxx=-1000,minn=1000;
	for(int i=0;i<n;i++)
	{
		//求出上层最小 下层最大 
		minn=min(minn,arr[0][i]);
		maxx=max(maxx,arr[1][i]);
	}
	int ans=minn-maxx;//相差得答案 
	if(ans>0)
		cout<<"Yes "<<ans;
	if(ans<=0)
		cout<<"No "<<abs(ans)+1; //先求绝对再加一 
} 

6,题目描述

给定一个长度为n的序列 1,2,...,a1​,a2​,...,an​ ,请问多少种方案,能够从中选取一个长度恰好为 m 的子段,且子段内所有数字的最大值不超过K?

输入格式

输入共两行:
输入第一行,三个正整数n,m,K
输入第二行,n个整数1,2,...,a1​,a2​,...,an​ 。

输出格式

输出一个整数,表示方案数

输入:

5 2 5
3 7 2 5 1

输出:

2

说明:

选取{2,5}和{5,1}均可,共两种方案

(试试优化到时间复杂度限为0(n))

#include<iostream>
using namespace std;
int arr[100005],n,m,k;
int num,ans;//num为选中数的个数 
int main()
{
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++)
	{
		cin>>arr[i];
		num++;
		if(arr[i]>k) 
		{//一旦发现有大于k的就从新置零 
			num=0;
		}
		else if(num==m)//积累的长度达到目标 
		{
			num--;//相当于往后面移动一位 继续判断 
			ans++;//找到了一种可能 答案加一 
		}
	}
	cout<<ans;
} 

7,题目描述

如果两个整数各位数字的和是一样的,则被称为是“朋友数”,而那个公共的和就是它们的“朋友证号”。例如 123 和 51 就是朋友数,因为 1+2+3 = 5+1 = 6,而 6 就是它们的朋友证号。给定一些整数,要求你统计一下它们中有多少个不同的朋友证号。

输入格式:

输入第一行给出正整数 N。随后一行给出 N 个正整数,数字间以空格分隔。题目保证所有数字小于 10000。

输出格式:

首先第一行输出给定数字中不同的朋友证号的个数;随后一行按递增顺序输出这些朋友证号,数字间隔一个空格,且行末不得有多余空格。

输入样例:

8
123 899 51 998 27 33 36 12

输出样例:

4
3 6 9 26

#include<iostream>
using namespace std;
int ans[40],cnt;

void fun(int n)
{
	int sum=0;//记录各个数位上的总和 
	while(n)//计算各个数位的值 
	{
		sum+=n%10;
		n/=10;
	}
	if(ans[sum]==0)//如果没有被记录过 
	{
		cnt++;//不同的证号加一 
		ans[sum]++;
	}
}

int main()
{
	int n,t;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>t;//输入需要处理的数字 
		fun(t);//处理输入的数字 
	}
	
	cout<<cnt<<endl;
	int out=0;//记录输出的次数 
	for(int i=0;i<40;i++)
		if(ans[i]!=0)
			if(out==cnt-1)//输出的最后一位了 
			{
				cout<<i;
				break;
			}
			else
			{
				cout<<i<<" ";	
				out++;
			} 
}

8,题目描述

观察下面的数字金字塔。

写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。

        7 
      3   8 
    8   1   0 
  2   7   4   4 
4   5   2   6   5 

在上面的样例中,从 7→3→8→7→5的路径产生了最大

输入格式

第一个行一个正整数 r ,表示行的数目。

后面每行为这个数字金字塔特定行包含的整数。

输出格式

单独的一行,包含那个可能得到的最大的和。

输入样例

5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5 

输出样例

30
#include<iostream>
using namespace std;
int arr[1005][1005];
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=i;j++)
			cin>>arr[i][j];//按要求完成输入 
			
	for(int i=n-1;i>=1;i--)//从最底层开始递推 
		for(int j=1;j<=i;j++)//计算每一层的各个位置的最大 
			arr[i][j]+=max(arr[i+1][j],arr[i+1][j+1]); 
	cout<<arr[1][1]; 
} 

9,题目描述

对于给定的一个长度为 N 的正整数数列 Ai​,现要将其分成连续的若干段,并且每段和不超过 M(可以等于M),问最少能将其分成多少段使得满足要求。

输入格式

第1行包含两个正整数 N,M,表示了数列 Ai​ 的长度与每段和的最大值,第 2 行包含 N 个空格隔开的非负整数 Ai​,如题目所述。

输出格式

一个正整数,输出最少划分的段数。

输入

5 6
4 2 4 5 1

输出

3
#include<iostream>
using namespace std;
int main()
{
	int n,m,t,sum=0,cnt=1;
	cin>>n>>m;
	while(n--)
	{
		cin>>t;//边输入边处理 
		if(sum+t<=m)
			sum+=t;//可以放下 
		else 
		{
			sum=t;//放不下了 
			cnt++;//重写开一个段 
		}
	}
	cout<<cnt;
}

10,题目描述

由于乳制品产业利润很低,所以降低原材料(牛奶)价格就变得十分重要。帮助 Marry 乳业找到最优的牛奶采购方案。

Marry 乳业从一些奶农手中采购牛奶,并且每一位奶农为乳制品加工企业提供的价格可能相同。此外,就像每头奶牛每天只能挤出固定数量的奶,每位奶农每天能提供的牛奶数量是一定的。每天 Marry 乳业可以从奶农手中采购到小于或者等于奶农最大产量的整数数量的牛奶。

给出 Marry 乳业每天对牛奶的需求量,还有每位奶农提供的牛奶单价和产量。计算采购足够数量的牛奶所需的最小花费。

注:每天所有奶农的总产量大于 Marry 乳业的需求量。

输入格式

第一行二个整数 n,m,表示需要牛奶的总量,和提供牛奶的农民个数。

接下来 m 行,每行两个整数 pi​,ai​,表示第 i 个农民牛奶的单价,和农民 i 一天最多能卖出的牛奶量。

输出格式

单独的一行包含单独的一个整数,表示 Marry 的牛奶制造公司拿到所需的牛奶所要的最小费用。

输入

100 5
5 20
9 40
3 10
8 80
6 30

输出

630
#include<iostream>
using namespace std;
struct man{//农民结构体 
	int x;//售价 
	int y;//数量 
};

int n,m;
man arr[5005];//结构体数组 
void paixu()
{//利用冒泡排序进行排序 
	for(int i=0;i<m;i++)
		for(int j=i+1;j<m;j++)
			if(arr[i].x>arr[j].x)
			{//根据x 售价进行排序 
				man t=arr[i];
				arr[i]=arr[j];
				arr[j]=t;
			}
}

int main()
{
	cin>>n>>m;
	for(int i=0;i<m;i++)
		cin>>arr[i].x>>arr[i].y;
	
	paixu();//排序函数 

	int ans=0,sum=0;
	for(int i=0;i<m;i++)
	{
		if(sum+arr[i].y<n)
		{
			sum+=arr[i].y;
			ans+=arr[i].x*arr[i].y;
		}
		else//sum+arr[i].y>=n
		{
			ans+=arr[i].x*(n-sum);
			break;
		}
	}
	cout<<ans;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值