蓝桥杯:真题讲解2(C++版)附带解析

星系炸弹

来自:2015年六届省赛大学B组真题(共6道题)

分析:这题涉及到平年和闰年的知识,如果我们要解这题,首先要知道每月有多少天,其实也就是看2月份的天数,其它月份的天数都是一样的,只有2月有点不同。

平年的2月有28天,闰年2月有29天,搞定如何判断平年和闰年,这题也就好解了。

闰年满足的条件:

  • 能被4整除且不能被100整除
  • 或者能被400整除

不是闰年就是平年。

代码演示:

cpp 复制代码
bool is_run(int year)
{
	if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) return true;
	else return false;
}

接下来我们模拟题意即可:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
  // 请在此输入您的代码
  int mon[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
  int y=2014,m=11,d=9;
  for(int i=0;i<1000;i++){
  	if((y%4==0&&y%100!=0) || (y%400==0)) mon[2]=29;
  	else mon[2]=28;
  	d++;
  	if(d>mon[m]){
  		d=1;
  		m++;
	  }
	  if(m>12){
	  	y++;
	  	m=1;  
		//这里不用写d=1,上面已经判断过了。 
	  }
  }
  printf("%04d-%02d-%02d",y,m,d);
  return 0;
}

移动距离

来自:2015年六届省赛大学B组真题(共6道题)

分析:实际上就是求两点间的距离

距离公式:点(x1,y1)到(x2,y2)的距离:|x1-x2|+|y1-y2|

解决方案:

我们还有一个问题,就是数列的排序是按照蛇形来排序的,那我们怎么处理有反向的数列呢,我们经过短暂的思考,立马给出了解决方案,先按照正常的方式来求,到了最后,我们发现当(x%2)==1 的时候,数的顺序是反的,然后我们就能调整了。

代码:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

int w, m, n;
int main() {
	scanf("%d%d%d", &w, &m, &n);

	m --;
	n --;//将两个数都进行减1操作
	int x1 = m / w, y1 = m % w;//求得正常排序下的,当前数的坐标
	int x2 = n / w, y2 = n % w;

	if (x1 % 2 ==1) y1 = w - y1 - 1;//标记反向数列的纵坐标
	if (x2 % 2 ==1) y2 = w - y2 - 1;//标记反向数列的纵坐标

	cout << abs(x1 - x2) + abs(y1 - y2) << endl;//曼哈顿距离公式

	return  0;
}

煤球数目

来自:2016年七届省赛大学B组真题(共6道题)

分析:找规律即可,第零层到第一层+1,第一层到第二层+2,第二层到第三层加+3,第三层到第四层+4,以此类推。

代码:

cpp 复制代码
#include <iostream>
using namespace std;
int main()
{
  // 请在此输入您的代码
  int sum=0,d=0;

  for(int i=1;i<=100;i++){
    d+=i;    //累积d的值,因为它的规律是+2 、 +3 、+4。
    sum+=d;
  }
  cout << sum;
  return 0;
}

生日蜡烛

分析:直接2层for循环暴力即可。

代码:

cpp 复制代码
#include <iostream>
using namespace std;
int main()
{
  // 请在此输入您的代码
  int i;
  for (i = 0; i < 100; i++) {   //i<100就行了,搞个大概就ok。
    int sum = 0;
    for (int j = i; j < 100; j++) {
      sum += j;
      if (sum == 236) break;
    }
    if (sum == 236) break;
  }
  cout << i;
  return 0;
}

四平方和

来自:2016年七届省赛大学B组真题(共6道题)

先用暴力求解,代码:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
  // 请在此输入您的代码
  long long N;
  cin >> N;

  for(int i=0;i<=N;i++){
    for(int j=0;j<=N;j++){
      for(int k=0;k<=N;k++){
        for(int m=0;m<=N;m++){
          if(i*i+j*j+k*k+m*m == N){
            int a[4]={0};
            a[0]=i;
            a[1]=j;
            a[2]=k;
            a[3]=m;
            sort(a,a+4);   
            cout << a[0] << " " << a[1] << " " << a[2] << " " << a[3];
            return 0;
          }
        }
      }
    }
  }
  return 0;
}

运行后只能过62.5%的测试数据,下面改进一下代码:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int main() {
	long long n,a,b,c,d;

	cin>>n;
	long long s=sqrt(n)+1;  //习惯上+1,不加也是正确的,每个正整数到不了一半。

	for(a=0; a<=s; a++) { //注意以下每个for循环前边初值继承上一循环体的值,保证从小到大的顺序
		for(b=a; b<=s; b++) {
			for(c=b; c<=s; c++) {
				for(d=c; d<=s; d++) {
					if(a*a + b*b + c*c + d*d == n) {
						cout<<a<<" "<<b<<" "<<c<<" "<<d;
						return 0;
					}
				}
			}
		}
	}
	return 0;
}

交换瓶子

来自:2016年七届省赛大学B组真题(共6道题)

代码(注释中标明了代码含义):

cpp 复制代码
#include <iostream>
using namespace std;
int main()
{
  // 请在此输入您的代码
  int a[10010];
  int n,res=0;
  cin >> n;
  for(int i = 1; i<=n;i++){
    cin >> a[i];
  }
  for(int i = 1;i <=n;i++){
    while(a[i]!=i){
      swap(a[i],a[a[i]]);           //瓶子是有序排放的,所以下标为1的位置就应该放1号
      res++;
    }
  }
  cout << res;
  return 0;
}
相关推荐
曙曙学编程几秒前
初级数据结构——树
android·java·数据结构
小技与小术4 分钟前
数据结构之树与二叉树
开发语言·数据结构·python
Beau_Will4 分钟前
数据结构-树状数组专题(1)
数据结构·c++·算法
迷迭所归处8 分钟前
动态规划 —— 子数组系列-单词拆分
算法·动态规划
爱吃烤鸡翅的酸菜鱼9 分钟前
Java算法OJ(8)随机选择算法
java·数据结构·算法·排序算法
hccee25 分钟前
C# IO文件操作
开发语言·c#
hummhumm30 分钟前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
hunandede37 分钟前
av_image_get_buffer_size 和 av_image_fill_arrays
c++
J老熊40 分钟前
JavaFX:简介、使用场景、常见问题及对比其他框架分析
java·开发语言·后端·面试·系统架构·软件工程
寻找码源1 小时前
【头歌实训:利用kmp算法求子串在主串中不重叠出现的次数】
c语言·数据结构·算法·字符串·kmp