蓝桥杯学会暴力稳拿省一
暴力算法是蓝桥杯竞赛中常用的策略之一,尤其适用于数据范围较小的问题。通过直接模拟问题的解决过程,暴力算法能够快速实现并获得部分分数。【掌握暴力算法,一般而言,能够确保完成3道题目,然后再完成2-3道套路题,拿到省一就没有太大问题啦】~
一、蓝桥杯竞赛的赛制和做题方法
01 赛制特点
蓝桥杯的赛制是oi赛制,通过测试点来获得分数,只能提交一次。与ACM比赛的赛制不同,ACM比赛只看是否过所有测试数据,没有部分分,但是可以不断提交,实时反馈结果。
02 做题策略
在蓝桥杯比赛中,要想拿到省一奖项,需要保证每道题都能拿到部分分数,并且在数据范围允许的情况下,尽量优化算法。具体策略如下:
- 拿到部分分数相对容易,但要拿到全部分数需要优化。
- 确定算法范围,暴力做法时间跨度高,但能拿到部分分。
- 计算时间复杂度,确定数据范围,优化算法范围。
二、暴力算法详解
暴力算法是通过模拟题干中的过程,每次选出剩余数字中最小数,最终得到所有分数的方法。以下是一些暴力算法的代码例题:
01 暴力遍历
题目:判断1到N中满足奇数位为奇数、偶数位为偶数的“好数”个数。
代码:
#include<bits/stdc++.h>
using namespace std;
int n;
int ans=0;
bool check(int x)
{
int tem = x;
int f=0;//0奇1偶
while(tem)
{
if(f==0)
{
if(tem%10 % 2 == 0)//奇数位为偶
{
return false;
}
}
else
{
if(tem%10 % 2 != 0)//偶数位为奇
{
return false;
}
}
tem /= 10;
if(f==0) f=1;
else f=0;
}
return true;
}
int main() {
cin>>n;
//遍历判断
for(int i=1;i<=n;++i)
{
if(check(i))
{
ans++;
}
}
cout<<ans;
return 0;
}
02 暴力枚举
题目:猜年龄。
代码:
#include<iostream>
#include<cmath>
#include<set>
#include<string>
#include<sstream>
using namespace std;
void i2s(int num, string & str)
{
stringstream ss;
ss << num;
ss >> str;
}
bool check(string str)
{
set<char>s;// 注意:此时set是char类型
for(int i=0; i < str.length(); i++)
{
s.insert(str[i]);
}
if(str.length() == 10 && s.size() == 10) return true;
return false;
}
int main()
{
int num1, num2;
for(int x = 10; x <= 32; x++)
{
num1 = x*x*x;
num2 = num1 * x;
if(num1 >= 1000 && num1 <= 9999 && num2 >= 100000 && num2 <= 999999){
// 将整数转为字符串
string str1, str2;
i2s(num1, str1);
i2s(num2, str2);
// 4位和6位 拼接后检查
if(check(str1 + str2))
{
cout << x;
}
}
}
return 0;
}
03 暴力循环
题目:数字游戏。
代码:
#include<stdio.h>
int main()
{
int n,k,t;
scanf("%d%d%d",&n,&k,&t);
int a[10000000]; a[1]=1;
int sum=0;
for(int i=1;i<=n*(t-1)+1;i++)
{
a[i]=a[i-1]+i-1;
}
for(int i=1;i<=n*(t-1)+1;i++)
{
if(a[i]/k!=0)
{
a[i]=a[i]-(a[i]/k)*k;
}
}
for(int i=1;i<=n*(t-1)+1;i++)
{
if(i%n==1)
{
sum+=a[i];
}
}
printf("%d",sum);
}
04 暴力枚举区间
题目:计算两个小组的区间力量和的差。
代码:
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
long long n,m,a[200005],sum[200005];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum[i]=sum[i-1]+a[i];
}
long long min1=1e9;
for(int l1=1;l1<=n;l1++)
{
for(int r1=l1;r1<=n;r1++)
{
for(int l2=r1+1;l2<=n;l2++)
{
for(int r2=l2;r2<=n;r2++)
{
min1=min(abs(sum[r1]-sum[l1-1]-sum[r2]+sum[l2-1]),min1);
}
}
}
}
cout<<min1;
return 0;
}
三、蓝桥杯中的常见“坑点”
01 main函数
结尾必须有return 0;
。
02 数据范围
注意数据类型,如int
和long long
,避免数据溢出。
03 输入输出速度
如果使用暴力的方法去做题,那么肯定会花费很多的时间,在输入输出方面可以用其他方式节省一点时间:
- 都用C语言的输入输出方式。
- 写上以下三行代码,输入输出速度会变快:
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
注意:cout
输出时,末尾不要用endl
换行,要用\n
;如果怕自己忘记,可以在文件开头就定义#define endl '\n'
。
04 万能头文件
#include <bits/stdc++.h>
它只会增加编译时间,并不影响运行时间,有时候很多方法,在特定头文件里面才能用的,又想不起来这个头文件的名字,这个时候记住上面这个头文件就好了。
05 提交代码时的C++标准
提交时的标准要大于等于你本地编译器中C++的标准。