2020蓝桥杯第一场

第一题:跑步训练(5分)
小明要做一个跑步训练。
初始时,小明充满体力,体力值计为 10000 。如果小明跑步,每分钟损耗 600 的体力。如果小明休息,每分钟增加 300 的体力。体力的损耗和增加都是均匀变化的。
小明打算跑一分钟、休息一分钟、再跑一分钟、再休息一分钟……如此循环。如果某个时刻小明的体力到达 0 ,他就停止锻炼。
请问小明在多久后停止锻炼。为了使答案为整数,请以秒为单位输出答案。答案中只填写数,不填写单位。

考点 模拟

#include<bits/stdc++.h> 
using namespace std;
int main(){
	int k = 10000;
	int i = 0;   //每当i = 60   t 变换一次 
	int t = 0;  //t = 0 体力减少,t = 1 体力增加 
	int s;      //记录秒数 
	while(1)    //直接用秒计算 
	{ i++;
	  s++;
	  if(!t)
	  { k = k - 10;
	     if(k == 0)
	    {	cout << s << endl;  //3880
	        break;
		}
	    if(i % 60 == 0)
		 t = 1;
	  }
	  else
	  { k = k + 5;
	    if( i % 60 == 0)
	      t = 0;
	  }
	}
	return 0;
}

第二题:纪念日(5分)
2020 年 7 月 1 日是中国 共 产 党 成立 99 周年纪念日。
中国 共 产 党 成立于 1921 年 7 月 23 日。
请问从 1921 年 7 月 23 日中午 12 时到 2020 年 7 月 1 日中午 12 时一共包含多少分钟?
 

#include<bits/stdc++.h>
using namespace std;
int check(int y)
{  if( y % 400 == 0 || y % 100 != 0 && y % 4 == 0)
   return 366;
   else
   return 365;
}
int main(){
	int sum = 0;
	for(int i =  1922; i <= 2019; i ++)
	{   sum += check(i);
	}
	cout << sum << endl;
	int sum2 = 0;
	
	if(check(2020) == 366) cout << "y";  //闰年  枚举 8 ,9,10,11,12 的月份 1,2,3,4,5,6 ,
	if(check(1991) == 365) cout << "y";  //非闰年 8,9,10,11,12 的月份 
	//之后从7月23到31的日子,最后sum 加上1922 年和 2020 年的日期  * 24 * 60
	//完全手动计算,大佬都是用Excel,我是菜狗只会代码+手动算 
	//52038720
	
	return 0;
} 

第三题:合并检测(10分)
题目描述
新冠疫情由新冠病毒引起,最近在 A 国蔓延,为了尽快控制疫情, A 国准备给大量民众进病毒核酸检测。
然而,用于检测的试剂盒紧缺。
为了解决这一困难,科学家想了一个办法:合并检测。即将从多个人( k 个)采集的标本放到同一个试剂盒中进行检测。如果结果为阴性,则说明这 k 个人都是阴性,用一个试剂盒完成了 k 个人的检测。如果结果为阳性,则说明至少有一个人为阳性,需要将这 k 个人的样本全部重新独立检测(从理论上看,如果检测前 k−1 个人都是阴性可以推断出第 k 个人是阳性,但是在实际操作中不会利用此推断,而是将 k 个人独立检测),加上最开始的合并检测,一共使用了 k+1 个试剂盒完成了 k 个人的检测。
A 国估计被测的民众的感染率大概是 1,呈均匀分布。请问 k 取多少能最节省试剂盒?
 

#include<bits/stdc++.h>
using namespace std;
int main(){
	/* 思路是暴力枚举一下,假设100个人有一个人得病,
	看一下当前i个人一起测最多用多少个试剂盒
	如果100/i不够除,让剩下的人都是单独用一个试剂盒测
	如果能够整除,需要再加上i个试剂盒,因为必然会有一个试剂盒检测出病人,需要每个人单独测
	//数学问题 
	*/ 
	int min = 1000;
	int k;
	int sum;   
	for(int i = 2; i <= 100; i ++) 
	{ 
	   sum = 100 /  i + i;
	   if(100 % i != 0)
	   { sum +=  100 % k;
	   }
	   if(sum < min)
	   { min = sum;
	     k = i;
	   }
	   
	}
	cout <<  k << endl; //10
	
	return 0;
}

附件 prog.txt 中是一个用某种语言写的程序。
其中 REPEAT k 表示一个次数为 k 的循环。循环控制的范围由缩进表达,从次行开始连续的缩进比该行多的(前面的空白更长的)为循环包含的内容。
例如如下片段:

REPEAT 2:
 A = A + 4
  REPEAT 5:
  REPEAT 6:
   A = A + 5
  A = A + 7
 A = A + 8
A = A + 9

该片段中从 A = A + 4 所在的行到 A = A + 8 所在的行都在第一行的循环两次中。
REPEAT 6: 所在的行到 A = A + 7 所在的行都在 REPEAT 5: 循环中。
A = A + 5 实际总共的循环次数是 2 × 5 × 6 = 60 次。
请问该程序执行完毕之后,A 的值是多少?
 

#include<bits/stdc++.h>
using namespace std;
int A;
int main(){
	//这道题看了半天没明白啥意思,后来看了一下就是for循环换了一个说法,理解能力太差,没办法,多做题吧 
	for(int i = 1; i <= 2; i ++)
	{  A = A + 4;
	  for(int j = 1; j <= 5; j ++)
	  {  for(int k = 1; k <= 6; k ++)
	      { A = A + 5;
		  }
		    A = A + 7;
	  }
	        A = A + 8;
	}
	A = A + 9;
	cout << A << endl; //答案 403
	return 0;
}

第五题:矩阵

题目描述
把 1∼2020 放在 2×1010 的矩阵里。要求同一行中右边的比左边大,同一列中下边的比上边的大。一共有多少种方案?
答案很大,你只需要给出方案数除以 2020 的余数即可。

这道题考的是dp,暂且还没学到这个算法,后面再补吧

第六题:整除序列(15分)
题目描述
有一个序列,序列的第一个数是 n,后面的每个数是前一个数整除 2,请输出这个序列中值为正数的项。
【输入格式】
输入一行包含一个整数 n。
【输出格式】
输出一行,包含多个整数,相邻的整数之间用一个空格分隔,表示答案。
【评测用例规模与约定】
对于 80% 的评测用例,1≤n≤109。
对于所有评测用例,1≤n≤1018。

#include<iostream>
using namespace std;
int main()
{
	long long n;//long long 的范围大概 10的19次方 送分题了别忘记数据开大一些
	cin>>n;
	while(n>0)
	{
		printf("%lld ",n); 
		n=n/2;
	 }
    return 0;
}

第七题:解码

小明有一串很长的英文字母,可能包含大写和小写。 在这串字母中,有很多连续的是重复的。小明想了一个办法将这串字母表达得更短:将连续的几个相同字母写成字母 + 出现次数的形式。
例如,连续的 5 个 a ,即 aaaaa ,小明可以简写成 a5 (也可能简写成 a4a 、 aa3a 等)。
对于这个例子:HHHellllloo ,小明可以简写成 H3el5o2 。为了方便表达,小明不会将连续的超过 9 个相同的字符写成简写的形式。
现在给出简写后的字符串,请帮助小明还原成原来的串

我写这道题时写了半个多小时,写的很复杂。题目读错了。最后还是AC了,哎,读题很重要

#include<iostream> //我写的很复杂的代码
#include<cstdio>
#include<cstring>
using namespace std;
int main(){
	string  s;
	string st;
    int flag = 0;
	cin >> s;
	int k1 = s.size()-1;
	for(int i = 0; i < s.size(); i ++)
	{   if(flag == 1) break;
	   if(s[i] >= 'A' &&  s[i] <= 'Z' || s[i] >= 'a' && s[i] <= 'z')
	    {
		  st += s[i];
	    }
	    else
		{ int t = 0;
		  int k = 0;
		  string s2;
		  for(int j = i; j < s.size(); j ++)
		  {  if(s[j] >= '0' && s[j] <= '9')
		     { t++;
		       s2 += s[j];
			 }
			 else
			 { k = j;
			   break;
			 }
		  }
		  if(t == s.size() - i) flag = 1;
		  
		  if(t > 2)
		   { st += s2;
		     s2.clear();
		   }
		  else
		   {  int t2 = s2[0]-'0';
		      for(int i = 1; i <= t2 -1; i ++)
		       st += st[st.size()-1];
		   }
	    }
	}
	for(int i = 0; i < st.size(); i ++) cout <<st[i];
	
	return 0;
}

就不写简单的代码思路

如果这个数是字母记录一下,下一个是数字字符的话,循环输出这个的这个字符

第八题:走方格
题目描述
在平面上有一些二维的点阵。
这些点的编号就像二维数组的编号一样,从上到下依次为第 1 至第 n 行,从左到右依次为第 1 至第 m 列,每一个点可以用行号和列号来表示。
现在有个人站在第 1 行第 1 列,要走到第 n 行第 m 列。只能向右或者向下走。
注意,如果行号和列数都是偶数,不能走入这一格中。
问有多少种方案。
【输入格式】
输入一行包含两个整数 n, m。
【输出格式】

3 4

2
输出一个整数,表示答案。
【评测用例规模与约定】
对于所有评测用例,1≤n≤30,1≤m≤30。
 

#include<iostream>
using namespace std;
const int N = 33;
int s[N][N];
int n,m,ans;
bool st[N][N];
int fx[2] = {0,1},fy[2] = {1,0};
void dfs(int x,int y)
{  if(x == n && y == m)
    {
        ans ++;
        return;
    }
   for(int i = 0; i < 2; i ++)
   {  int dx = x + fx[i];
      int dy = y + fy[i];
      if(!st[dx][dy] && x <= n && y <= m && !s[dx][dy])
      { st[dx][dy] = true;  //标记走过了
	    dfs(dx,dy);
	    st[dx][dy] = false; //回溯
	  } 
   }
   
}
int main()
{   //我个人用的dfs搜索,看到网上有人用dp,属实是真牛啊,代码写的还很短,
    // 还有贪心和dp没学还得加油  这个题的提交我是在c语言网提交的,如果有做的不对的地方,
    // 还请帮忙说一声。

    scanf("%d%d",&n,&m);
    for(int i = 1; i <= n; i ++)
     for(int j = 1; j <= m; j ++)
      {  if(i % 2 == 0 && j % 2 == 0)
          s[i][j] = 1;  //标记这个点
      }
      st[1][1] = true;
      dfs(1,1);
      //ans 表示 有多少个走法 提升一下,这道题的思路我看着和落谷题单递归中的马走棋盘
    cout << ans << endl;
    return 0;
}

后面两道题一个是模拟+STL ,另一个是并查集,都不会,后面慢慢补

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值