【蓝桥杯】赛前必看,找规律题万能解法!暴力打表+观察法秒杀!文末附所有代码

        引言

特点解析

一、报数游戏

二、阶乘求和

三、数字诗意

四、平方差

代码


引言

备战蓝桥杯的你是否曾被找规律题“卡脖子”?这类题目看似玄学,实则暗藏套路!

它们数据量爆炸(轻松超1e8)!它们让我们暴力枚举直接超时!

别慌!使用暴力打表前100项 + 观察周期 / 递推规律,才是破解这类题的终极钥匙!

本文手把手带你剖析找规律题的三大特征(高数据量、周期性、递推性),并通过四道经典例题实战演示如何用代码快速生成关键数据,从乱序数字中一眼锁定隐藏的数学规律,轻松避开溢出陷阱。文末附文章例题暴力打表代码,助你赛场上一招制胜,省时又省力!速速收藏,拒绝无效刷题!🚀

文章例题参考:

up主:溶金落梧桐

b站视频:蓝桥杯常考的找规律题,学会套路轻松拿捏

特点解析

找规律题的特点:

  • 数据量非常大(通常大于1e8),很容易溢出,不可能用代码暴力求出;
  • 有周期性;
  • 答案有递推关系;

通解:暴力输出前100项后找!规!律!

下面带着大家来看看例题:

一、报数游戏

https://www.lanqiao.cn/problems/19698/learning

 因为202420242024是很大的数字,所以直接考虑找规律;

我们按照题目中的暗示(给出前10个报出的数字),所以我们每10个数字换一次行,可以得到如下的输出:

观察可得:每次第10个数字,都是120的倍数,也可以说是12的倍数,更具体地来说:

  • 第10个数字:12 * 10 =120;
  • 第20个数字:12 * 20 =240;
  • 第30个数字:12 * 30 =360;
  • 第40个数字:12 * 40 =480;

到这里规律已经很明显了。所以,202420242020肯定也是12的倍数,按照上述规律可求得:

  • 第202420242020个数字:12 * 202420242020;

下面只需求出相邻组中,0到4所产生的变化。

很显然,120 -> 168(+48);240 -> 288(+48);360 -> 408(+48)......

所以我们只需加上48即可得到答案,最终计算式为:

  • 12 * 202420242020 + 48 = 2,429,042,904,288

提交,结果正确。


二、阶乘求和

https://www.lanqiao.cn/problems/3500/learning

我们首先看到202320232023!是一个很大的数字,故考虑直接找规律!

概念“阶乘尾0”:n!随着n的值变大,尾部的0会越来越多;

同样我们输出前100项数据的后9位,直接寻找规律: 

答案即为:420940313

提交,结果正确。

我们也可以尝试着取更多位数来验证阶乘尾0的概念,若mod=1e15:

 从上图也可以看到末位是逐渐稳定的!

警告:

时刻注意上限:const long mod = 1e9; 已是最大,超过则需换成更大的数据类型,如long long;


三、数字诗意

https://www.lanqiao.cn/problems/19714/learning

看到下面红圈内容,1e16的数据范围考虑是否有规律可找!

 

对于这个题目,我们考虑找到不蕴含诗意数字的特点,故输出前100、1000个数字中的情况:

找到不蕴含诗意数字

 很明显,我们发现都是2的倍数(加上1、2两个不优雅的数字),故我们可以猜测:若是2的倍数(0到n倍),则该数字不优雅!

所以题目变成了:从输入的数字中,去除2的倍数即可!

下一步则是剔除 2 的幂次方——up主没有往下讲这个,而是讲其他题去了,我接着进行了补全。由于题目的数据限制,这个地方比我想象中的要困难!!!

总是只能拿到30%的分,而对于最大的数据(1e16),我尝试开最大的__int128类型,但是仍然产生了溢出,导致结果不正确,这很令人头疼!

查阅题解和gpt后,我使用“ a & (a - 1) == 0 ”判断 a 是否是 2 的幂次方——据悉,这是一个“经典的技巧”......好吧,学习了。


四、平方差

https://www.lanqiao.cn/problems/3502/learning

同理:考虑到下面的平方和数值大小,我们采用找规律来尝试解题:

  理解题意:寻找平方差得到结果的特征!

对于题目中的公式进行拆分:x = y^2 - z^2 = (y-z)(y+z);

此时我们对于上述y、z两数的奇偶性进行讨论:

  • 当 y、z 一奇一偶,得奇数相乘,结果为奇数;
  • 当 y、z 同奇 / 同偶数,得到偶数相乘,结果为偶数,且能被4整除;

故即查找 [L, R] 间有多少个为奇数或者能被4整除的数!

又是经典结论......而且目前只能看出:

平方差的计算结果有这个性质;但是此处并未证明如果符合这个性质,一定是平方差的计算结果

所以先标记一下,应该是可证的。

但是!

又遇到问题了。正常的计算方法会由于溢出而只能通过90%的数据;

所以借鉴了他人的题解,使用 “ ans = get_sum(r)-get_sum(l-1); ”成功拿到100%;

其中 get_sum() 函数如下:

//获取[1...x]中 4的倍数 和 奇数的个数,前者下取整,后者上取整
ll get_sum(ll x){
    return x / 4 + (x + 1) / 2;
}

 思路(来自平方差-louvre的代码):

  • x/2上取整可以获得[1,x]奇数个数: ⌈9 / 2⌉ = 5(1,3,5,7,9为[1,x]的奇数)
  • x/4下取整可以获得[1,x]4的倍数的个数⌊5 / 4⌋ = 1(只有4一个为4的倍数)

再分别获取[1...r]和[1...l-1]区间内两种数字个数做差减去交集,即可得到答案。


代码

1、报数游戏

#include <bits/stdc++.h>
using namespace std;

int cnt=0;

int main()
{
	for(int i=1;cnt<100;i++){
		if(i%20==0 || i%24==0){
			cnt++;
			cout<<i<<' ';
			if(cnt%10==0) cout<<endl;
		}
	}
	return 0;
}

2、阶乘求和

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const long long mod = 1e9;

int main()
{
	ll sum=0;	// 结果 
	ll fac=1;	// 阶乘(一直往上乘) 
	for(int i=1;i<=100;i++){
		fac=(fac*i)%mod;
		sum=(sum+fac)%mod;
		cout<<sum<<endl;
	}
	return 0;
}

3、数字诗意

part1:不蕴含诗意数字的特点

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

// check a  
int check(int a){
	for(int j=1;j<a;j++){
		int sum=0;
		for(int k=j;k<a;k++){
			sum+=k;
			if(sum==a) return 1;
		}
	}
	return 0;
}

int main()
{
	// 尝试输出3~100中不优雅的数字 
	for(int i=3;i<=1000;i++){
		if(!check(i)) cout<<i<<endl;
	}
	return 0;
}

part2:剔除( 技巧:(a&(a-1))==0来剔除 2 的幂次方

#include <iostream>
using namespace std;
typedef long long ll;

int main()
{
  ll n,ans=0,a;
  cin>>n;

  for(ll i=0;i<n;i++){
      cin>>a;
      if((a&(a-1))==0) ans++;    // 判断2^n
  }
  cout<<ans;
  return 0;
}

4、平方差

#include <iostream>
typedef long long ll;
using namespace std;

//获取[1...x]中 4的倍数 和 奇数的个数,前者下取整,后者上取整
ll get_sum(ll x){
    return x / 4 + (x + 1) / 2;
}

int main()
{
  ll l,r;
  ll ans=0;
  cin>>l>>r;
//   for(ll i=l;i<=r;i++){     // 90%
//       if(i%4==0 || i%2==1) ans++;
//   }
  ans = get_sum(r)-get_sum(l-1);
  cout<<ans;
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值