当前位置: 首页 > article >正文

【蓝桥杯14天冲刺课题单】Day 1

 1. 题目链接:19937 艺术与篮球

该题目的难点主要在20240413这个日期需要结束程序跳出循环。最开始将该输出ans的位置放在了for循环之外,此时的日期已经循环完了2024年所有的日期,则最后会统计多而导致结果错误。

AC代码:

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int day_1[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};//用数组预处理每月的天数
int day_2[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int sum_num[10]={13,1,2,3,5,4,4,2,2,2};//预处理每一个数字的文字笔画
bool check_year(int year) //判断闰年,便于选择月份
{
	if((year%4 == 0 && year%100!=0)||(year%400 == 0)) 
		return 1;
	else return 0;	
}
int main()
{
	int ans=0,result=0,m,d,sum=0;
	for(int y=2000;y<=2024;y++)
	{
		if(check_year(y) == 1) 
		{
			for(m=1;m<=12;m++)
			{
				for(d=1;d<=day_1[m];d++)
				{
					sum=0;
					result=(y*10000)+(m*100)+d;
					while(result)
					{
						sum += sum_num[result%10];
						result=result/10;
					}
					if(sum > 50) ans++;
					if ((y == 2024) && (m >= 4) && (d >= 13)) 
					{
						cout<<ans;
						return 0;
					}//就是这一段输出的位置需要注意
				}
			}
		}
		else if(check_year(y) == 0) 
		{
			for(m=1;m<=12;m++)
			{
				for(d=1;d<=day_2[m];d++)
				{
					sum=0;
					result=(y*10000)+(m*100)+d;
					while(result)
					{
						sum += sum_num[result%10];
						result=result/10;	
					}
					if(sum > 50) ans++;	
					if ((y == 2024) && (m >= 4) && (d >= 13)) 
					{
					cout<<ans;
					return 0;
					}//已知2024是闰年,此处可以不需要这个输出
				}
			}
		}
	}
} 

这个方法有重复的代码,需要简化。


 2.题目链接: 3491 幸运数

该题目为填空题,可以直接进行输出。

最开始的算法是将每一个数字进行拆分,算出位数,再进行判断是否为偶数位。接着判断该数的左右两边的和是否相等,最后进行个数统计。这里因为数字是从后往前分离的,且是偶数位,则可以先统计后面的,到一半的长度时停止,再换另一个计数器统计前一半。但测评结果是TLE。那么不能使用直接分离的方法。

TLE的枚举代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#pragma GCC optimize(2)
using namespace std;
int check_number(int num)
{
	int ans=0;
	while(num)
	{
		num=num/10;
		ans++;
	}
	if(ans%2 == 0) return ans;
	else return 0;
}
int main() 
{
	int result=0;
	for(int i=10;i<=100000000;++i)
	{
		int sum_1=0,sum_2=0,half;
		int number=i;
		if(check_number(i) != 0)
		{
			half=check_number(i)/2;
			for(int j=1;j<=half;j++)
			{
				sum_1 += number%10;
				number /=10;
			}
			for(int j=1;j<=half;j++)
			{
				sum_2 += number%10;
				number /=10;
			}
			if(sum_1 == sum_2) result++;
		}
		else continue;
	}
	cout<<result;
	return 0;
}

 根据蓝桥杯的官方题解,可以将数字转换成字符串,则可以用字符串相关的函数直接得出结果数字的长度,进而判断数字是否为偶数位。这个方法直接将时间复杂度从O(n)降到了O(1)。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int ans = 0;
    for (int i = 1; i <= 100000000; ++i) 
    {
        string s = to_string(i); //直接转换成字符串,便于统计数字长度,时间复杂度为O(1);
        int n = (int)s.size();
        if (n % 2) continue;
        int l = 0, r = 0;
        for (int j = 0; j < n; ++j) 
        {
            if (j < n / 2) l += s[j] - '0';//字符转换为数字
            else r += s[j] - '0';
        }
        if (l == r) ans++;
    }
    cout << ans << '\n';//4430091
    return 0;
}

3. 题目链接:1600 平方差

根据条件,最大的数字不超过2021,则可以将1到2021的所有可能性枚举出来。

同时因为a^2-b^2 =(a + b)(a-b),用sum数组进行统计,只要满足1到2021之间这个条件的数字就存入数组,不用管是否为1个拆分方式;最后遍历数组,存了数字的数组就计数器加1。因为是开的全局数组可以不用memset数组为0。 

#include <iostream>
#include <cstdio>
using namespace std; 
const int maxn=1e7;
int sum[maxn];
int main()
{
	int result,ans=0;
	for(int i=1;i<=2021;i++)
	{
		for(int j=0;j<i;j++)
		{
			result=(i+j)*(i-j);
			if(result>=1&&result<=2021) sum[result]++;
		}
	}
	for(int i=1;i<=2021;i++)
	{
		if(sum[i]!=0)
		{
			ans++;
		}
	}
	cout<<ans;
	return 0;
}

!!一开始无思路的题

4. 题目链接:19732 小球反弹

首先根据题目, 将小球的运动方向拆解为x轴方向上的运动和y轴方向的运动。设小球在x轴方向的运动距离d_x = 15t,y轴方向上的运动距离为d_y = 17t。根据勾股定理,小球每秒移动的距离d =\sqrt{d_x^2+d_y^2}

当小球 A 回到起点时,说明其在水平方向上的移动距离是长方形长度L_x = 343720的偶数倍,在垂直方向上的移动距离是长方形宽度L_y = 233333的偶数倍。因为小球碰壁反弹的路径与原来的路径相同,那么相同的路径走了偶数倍。

假设从开始到结束,小球总共花费了t 秒,那么有:

d_x = 15td_y = 17t

同时需要满足: \frac{d_x}{L_x} = 2k_1,(k_1 \in N^*)\frac{d_y}{L_y} = 2k_2,(k_2 \in N^*)

由此,对 t 进行枚举,直至找到满足 15t 整除 343720且17t 整除 233333,\frac{d_x}{L_x}和 \frac{d_y}{L_y}均为偶数的 t。

最终求得答案为 1100325199.77

需要注意的是,所求答案需要保留两位小数,则距离的数据类型需要用double。

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define ll long long int
bool check(ll a,ll b)
{
	if((a % b == 0)&&((a/b)%2 == 0)) return 1;
	else return 0;
}
int main()
{
	ll x=343720,y=233333;
	ll lx,ly;
	double dis;
	ll t;
	for(ll i=1;;i++)
	{
		t=i;
		lx=15*t;
		ly=17*t;
		if(check(lx,x) && check(ly,y)) break;
	}
	dis=sqrt(15*t*15*t+17*t*17*t);
	printf("%.2lf",dis);
	return 0;
}

 


http://www.kler.cn/a/614761.html

相关文章:

  • 跟着StatQuest学知识08-RNN与LSTM
  • prometheus+grafana监控虚拟机实操
  • Kinova Gen3:重新定义手术机器人的精度革命
  • 计算机底层基石:原码、反码、补码、移码深度剖析
  • python基础学习二(列表及字典的使用)
  • 解决MySQL GTID模式下的“CREATE TABLE ... SELECT“报错:完整指南与最佳实践
  • 红宝书第二十一讲:详解JavaScript的模块化(CommonJS与ES Modules)
  • vue3+bpmn.js基本使用
  • 使用msmtp和mutt在CentOS上发送指定目录下的所有文件作为邮件附件
  • Go 语言规范学习(4)
  • IvorySQL:兼容Oracle数据库的开源PostgreSQL
  • Java设计模式--单例模式
  • 从零开始搭建Anaconda环境
  • 霸王茶姬小程序(2025年1月版)任务脚本
  • HTML5 Web SQL 数据库学习笔记
  • HTML DOM 基础:用「家族树」理解网页操控术
  • 排序--归并排序--非递归
  • Ludic:用Python构建HTML,告别JavaScript的繁琐开发
  • 关于拉普拉斯变换小记
  • vue 脚手架解决跨域问题