0
点赞
收藏
分享

微信扫一扫

蓝桥杯自用

f12b11374cba 2022-04-02 阅读 40
c++蓝桥杯

2020第四题:跑步锻炼
题目描述

小蓝每天都锻炼身体。正常情况下,小蓝每天跑1千米。如果某天是周一或者月初(1日),为了激励自己,小蓝要跑2千米。如果同时是周一或月初,小蓝也是跑2千米。小蓝跑步已经坚持了很长时间,从2000年1月1日周六(含)到2020年10月1日周四(含)。请问这段时间小蓝总共跑步多少千米?

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int run[2][13]={{0,31,29,31,30,31,30,31,31,30,31,30,31},{0,31,28,31,30,31,30,31,31,30,31,30,31}};
//run[0]表示闰年每个月的天数,run[1]表示非闰年的天数
int main()
{
	int y1,m1,d1;//初始日期
	y1=2000,m1=1,d1=1;
	int tmp=0;
	
	int week_num=6;//表示当前你是周几 
	
	int sum=0;//小蓝最终跑步的公里 
	while(!(y1==2020&&m1==10&&d1==1)){
		if(week_num==1||d1==1) sum=sum+2;//非正常+2 
		else sum=sum+1;//正常情况,包含当天 
		tmp++; 
		//天数+1
		d1++;
		week_num++;
		if(week_num==8) week_num=1;//如果星期八,变成星期一 
		
		//判断天数是否合法
		int f=(y1%4==0&&y1%100!=0)||(y1%400==0)?0:1;
		if(d1>run[f][m1]){d1=1;m1++;} 
		//判断月份是否合法
		if(m1==13){m1=1;y1++;} 
	} 
	cout<<tmp+1<<endl;//最后一一天没算上,所以加一 
	cout<<week_num<<endl;
	sum=sum+2;//最后一天是月初所以要加2 
	cout<<"小蓝一共跑了"<<sum<<"km"<<endl; 
	return 0;
} 

答案8879

2019第四题:数的分解(10分)

题目描述
把 2019分解成 3个各不相同的正整数之和,并且要求每个正整数都不包
含数字2和4,一共有多少种不同的分解方法?
注意交换 3个整数的顺序被视为同一种方法,例如 1000+1001+18和
1001+1000+18被视为同一种。

#include<iostream>
using namespace std;

int i,j,z;

bool is(int x){
int tmp=0;
while(x){
tmp=x%10;
if(tmp==2||tmp==4){
return false;
}
x/=10;
}
return true;
}
int main(){
int num=0;
for(i=1;i<2019;i++){
if(is(i))
for(j=i+1;j<2019-i;j++){
if(is(j)){
z=2019-i-j;
if(is(z)&&z>j){
num++;
}
}
}
}
cout<<num<<endl;
return 0;
}

答案 40785 

2018第四题:测试次数
题目描述

x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。
各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通。

x星球有很多高耸入云的高塔,刚好可以用来做耐摔测试。塔的每一层高度都是一样的,与地球上稍有不同的是,他们的第一层不是地面,而是相当于我们的2楼。

如果手机从第7层扔下去没摔坏,但第8层摔坏了,则手机耐摔指数=7。
特别地,如果手机从第1层扔下去就坏了,则耐摔指数=0。
如果到了塔的最高层第n层扔没摔坏,则耐摔指数=n

为了减少测试次数,从每个厂家抽样3部手机参加测试。

某次测试的塔高为1000层,如果我们总是采用最佳策略,在最坏的运气下最多需要测试多少次才能确定手机的耐摔指数呢?

请填写这个最多测试次数。

注意:需要填写的是一个整数,不要填写任何多余内容。

代码分析:这是一个动态规划问题,状态标识用f[i][j],因素:表示还有i部手机,还有j楼层待检测

将j层楼层划分成j个区域,每个区域都会有类似的状态。

状态分析:假设在k(1<=k<=j)层楼摔下去

摔碎了:手机i-1;待检测楼层数变成1~k层        即f[i-1][k-1]

没摔碎:手机不变;待检测的楼层数变成1~k-1层,        即f[i][j-(k+1)+1]

求的是最坏的运气:也就是检测次数最多,,max(f[i-1][k-1],f[i][j-(k+1)+1])+1,最后的+1是因为第一层是二楼

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

const int N=100000;
int f[4][N];
int main(){
int n;
cin>>n;
//讲摔手机次数初始化为楼层数
for(int i=1;i<=3;i++){
for(int j=0;j<=n;j++){
f[i][j]=j;
}
}
for(int i=2;i<=3;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=j;k++){
f[i][j]=min(f[i][j],max(f[i-1][k-1],f[i][j-(k+1)+1])+1);
}
}
}
cout<<f[3][n];
return 0;
}

2017第四题:方格分割(17分)
题目描述

6x6的方格,沿着格子的边线剪开成两部分。
要求这两部分的形状完全相同。
如图:p1.png, p2.png, p3.png 就是可行的分割法

试计算:
包括这3种分法在内,一共有多少种不同的分割方法。
注意:旋转对称的属于同一种分割法。
请提交该整数,不要填写任何多余的内容或说明文字。

 代码描述:一共有多少种不同的方法,实际上是dfs全局搜索。迷宫和方格都是要设置一个数组,看有没有访问过,注意点数是方格数,此处6*6方格,数组的边界大小就要设置为7。

还要注意还原,访问过一次要恢复一下访问占用的数组。

重复的不算在内,方格可以顺时针旋转4次,结果除四。

#include<iostream>
using namespace std;
int visit[7][7];
int ans=0;
int direction[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
void dfs(int x,int y){
	//边界情况
	if(x==0||y==0||x==6||y==6){
		ans++;
		return ;
	} 
	//数组方向 
	visit[x][y]=1;
	visit[6-x][6-y]=1;
	for(int i=0;i<4;i++){
		int nx=x+direction[i][0];
		int ny=y+direction[i][1];
		if(nx>-1&&nx<7&&ny>-1&&ny<7 and visit[nx][ny]==0){//位置合法,数组还没有被访问过 
			dfs(nx,ny);
		}
	}
	visit[x][y]=0;
	visit[6-x][6-y]=0;
}
int main(){
	dfs(3,3);
	cout<<ans/4<<endl;
	return 0;
}

2016第四题:快速排序
题目描述

排序在各种场合经常被用到。
快速排序是十分常用的高效率的算法。
其思想是:先选一个“标尺”,
用它把整个队列过一遍筛子,
以保证:其左边的元素都不大于它,其右边的元素都不小于它。
这样,排序问题就被分割为两个子区间。
再分别对子区间排序就可以了。
下面的代码是一种实现,请分析并填写划线部分缺少的代码。

#include <stdio.h>
void swap(int a[], int i, int j)
{
int t = a[i];
a[i] = a[j];
a[j] = t;
}
int partition(int a[], int p, int r)
{
int i = p;
int j = r + 1;
int x = a[p];
while(1)
{
while(i<r +i]<x);
while(a[--j]>x);
if(i>=j) break;
swap(a,i,j);
}
______________________;//填空
return j;
}
void quicksort(int a[], int p, int r)
{
if(p<r)
{
int q = partition(a,p,r);
quicksort(a,p,q-1);
quicksort(a,q+1,r);
}
}

int main()
{
int i;
int a[] = {5,13,6,24,2,8,19,27,6,12,1,17};
int N = 12;
quicksort(a, 0, N-1);
for(i=0; i<N; i++)
printf("%d ", a[i]);
printf("\n");
return 0;
}

快速排序算法是十大经典算法之一,填空部分的函数是用于切割,表示比当前的数小的放左边,比当前数大的放右边,然后依次对左边和右边进行排序。填空部分就是在分完之后,将当前的数进行交换位置。swap(a,i,j);交换的是索引,swap(a,p,j)交换的是位置。 //选定第一个表示a[p],p=0,即第一个元素,

 i从数组前面向后移,j从数组后面向前移动。i停在比a[p]大的位置,j停在比a[p]小的位置,交换他俩的位置,到i>=j的时候停止移动,这时候,p位置到j位置是小于a[p]的元素,j+1位置到i位置都是大于a[p]的元素,该段代码的目的是标尺的左边都是小于它的数,右边都是大于它的数,所以要将p位置的元素和j位置的元素进行交换。

  swap(a,p,j);

2015第四题:格子中输出

题目描述
StringInGrid函数会在一个指定大小的格子中打印指定的字符串。
要求字符串在水平、垂直两个方向上都居中。
如果字符串太长,就截断。
如果不能恰好居中,可以稍稍偏左或者偏上一点。
下面的程序实现这个逻辑,请填写划线部分缺少的代码。

#include <stdio.h>
#include <string.h>

void StringInGrid(int width, int height, const char* s)
{
int i,k;
char buf[1000];
strcpy(buf, s);//strcpy是C++语言的一个标准函数,strcpy把含有'\0'结束符的字符串复制到另一个地址空间,返回值的类型为char*。把s里面的放到buf里面。
if(strlen(s)>width-2) buf[width-2]=0;//字符串的长度大于现有的宽度,buf里面的内容就截断了。

printf("+");
for(i=0;i<width-2;i++) printf("-");
printf("+\n");

for(k=1; k<(height-1)/2;k++){
printf("|");
for(i=0;i<width-2;i++) printf(" ");
printf("|\n");
}

printf("|");

printf("%*s%s%*s",_____________________________________________); //填空

printf("|\n");

for(k=(height-1)/2+1; k<height-1; k++){
printf("|");
for(i=0;i<width-2;i++) printf(" ");
printf("|\n");
}

printf("+");
for(i=0;i<width-2;i++) printf("-");
printf("+\n");
}

int main()
{
StringInGrid(20,6,"abcd1234");
return 0;
}

代码说明:

C语言%*s用法

1、在scanf中使用,则添加了*的部分会被忽略(跳过),不会被参数获取。

例如:

int a,b;  

char b[10];  

scanf("%d%*s",&a,b);  

输入为:

12 abc

那么12将会读取到变量a中,但是后面的abc将在读取之后抛弃,不赋予任何变量(例如这里的字符数组b)

用*和扫描集配合,可以从输入中只选出需要的内容,而忽略其余的东西。

另外,也常用于清空缓冲区。 

2、在printf中使用,*表示用后面的形参替代*的位置,实现动态格式输出。

例如:

printf("%*s", 10, s); /*意思是输出字符串s,但至少占10个位置,不足的在字符串s左边补空格,这里等同于printf("%10s", s);*/  

printf("%.*s\n",int,str) ;   

// %.*s 其中的.*表示显示的精度 对字符串输出(s)类型来说就是宽度  

// 这个*代表的值由后面的参数列表中的整数型(int)值给出  

例如:  

printf("%.*s\n", 1, "abc");// 输出a  

printf("%.*s\n", 2, "abc");// 输出ab  

printf("%.*s\n", 3, "abc");// 输出abc >3是一样的效果 因为输出类型type = s,遇到'\0'会结束  

这里左右一样,左边总的宽度(width/2),左边总的字符串strlen(s)/2,但是左边有一个“|”,所以要减1,这段作为左边字符串的输出长度。将%s的内容,buf放入即可。

printf("%*s%s%*s",(width/2)-strlen(s)/2-1," ",buf,(width/2)-strlen(s)/2-1," ");
举报

相关推荐

0 条评论