蓝桥杯赛前自救攻略,备赛抱佛脚指南

Posted BingeBlog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯赛前自救攻略,备赛抱佛脚指南相关的知识,希望对你有一定的参考价值。

目录

前言

明天就要开始蓝桥杯了,然鹅还什么都没准备,就挺秃然的,凉凉但是还是要抱一下佛脚。这里分享一下上届蓝桥杯C++组混子选手的赛前自救笔记!以下是chatGPT的回答

蓝桥杯是国内最具影响力的计算机比赛之一,参赛选手要面对各种难度的编程题目。以下是蓝桥杯比赛前一天备赛的建议:

复习考试范围:蓝桥杯比赛有不同的组别和考试科目,请认真阅读比赛规则和考试范围,并适当调整复习计划。

解决模拟试题:尝试做一些类似于蓝桥杯的模拟试题,这些试题可以帮助您熟悉比赛的形式和难度,提高解题能力。

休息和放松:在比赛前一天,保持良好的身体状态非常重要。请注意充足的睡眠、饮食和运动,并避免过度紧张和焦虑。

熟悉编程环境:请熟悉自己常用的编程语言和开发环境,并进行必要的配置和测试,以确保在比赛时顺利运行程序。

增强信心和决心:蓝桥杯比赛需要很强的耐心和决心,因此在比赛前一天加强自我调整和心理暗示,提高自信和决心。

最后,祝愿所有参加蓝桥杯比赛的选手能够发挥出自己最好的水平,取得优异的成绩!


说的真好,但是我就偏不这么做,以下为个人备战分享经验:

  1. 首先,打编程比赛连语言都不会你打个得er啊,肯定是得去复习语言啊!对于C++选手来说的话就是STL
  2. 其次,各种宝典啊什么手册啊都不如你直接去看官网划的考试范围,然后把每个类型的找例题复习复习知识点。
  3. 最后,直接真题从最新往前推,能推多少是多少,这样一来把编程环境也熟悉了,剩下的看造化了。佛祖保佑!

一、复习语言知识

打编程比赛连语言都不会你打个得er啊,首先肯定是得去复习语言啊!对于C++选手来说的话就是STL

1、代码起手框架

#include <bits/stdc++.h>
using namespace std;
int main()
	return 0;

2、vector初始化

vector<vector<int>> matrix(M,vector<int>(N,data)); //初始化为m行,n列,data值
vector<vector<int>> matrix2 1,1,1 ;//大括号初始化二维数组
vector<vector<vector<int>>> cube(5, vector<vector<int>>(3, vector<int>(2, 0)));//三维容器初始化为长宽高:2*3*5

int main() 	// 行列不固定初始化二维数组
    vector<vector<int>> matrix;//行,列数不固定
    cout << "please input rows of matrix: " << endl;
    int rows;
    cin >> rows;
    matrix.resize(rows);
    int col;
    vector<int> temp;
    for (int i = 0; i < rows; i++) 
        cout << "please input the cols of " << i << "th row" << endl;
        cin >> col;//确定第i行的列数
        cout << i << "th row has " << col << " cols," << "please input these" << endl;
        for (int j = 0; j < col; j++)
            int data;
            cin >> data;
            temp.push_back(data);
        
        matrix[i] = temp;
        temp.clear();
    

    cout << "output matrix:" << endl;
    for (int i = 0; i < matrix.size(); i++) 
        for (int j = 0; j < matrix[i].size(); j++) 
            cout << matrix[i][j] << " ";
        
        cout << endl;
    
    cout << endl;
    return 0;

  • 如果题目在返回空的二维vector时,返回的是 [],这是我们程序中对应用;
  • 如果题目在返回空的二维vector时,返回的是 [[]],这是我们程序中对应用

2、unordered_map

#include <iostream>  
#include <unordered_map>  
#include <map>
#include <string>  
using namespace std;  
int main()  
  
	//注意:C++11才开始支持括号初始化
    unordered_map<int, string> myMap= 5, "张大" , 6, "李五" ;//使用赋值
    myMap[2] = "李四";  //使用[ ]进行单个插入,若已存在键值2,则赋值修改,若无则插入。
    myMap.insert(pair<int, string>(3, "陈二"));//使用insert和pair插入
  
	//遍历输出+迭代器的使用
    auto iter = myMap.begin();//auto自动识别为迭代器类型unordered_map<int,string>::iterator
    while (iter!= myMap.end())
      
        cout << iter->first << "," << iter->second << endl;  
        ++iter;  
      
	
	//查找元素并输出+迭代器的使用
    auto iterator = myMap.find(2);//find()返回一个指向2的迭代器
    if (iterator != myMap.end())
	    cout << endl<< iterator->first << "," << iterator->second << endl;  
    return 0;  
  

3、输入输出问题

vector<int> ratings;
int x;
while(cin>>x)
	ratings.push_back(x);
	if(cin.get()=='\\n') break;

二、复习考试范围知识

各种宝典啊什么手册啊都不如你直接去看官网划的考试范围,然后把每个类型的找例题复习复习知识点。

  • 计算机算法:

    枚举、排序、搜索、计数、贪心、动态规划、图论、数论、博弈论、概率论、计算几何、字符串算法等。

  • 数据结构:

    数组、对象/结构、字符串、队列、栈、树、图、堆、平衡树/线段树、复杂数据结构*、嵌套数据结构*等。

1、深度优先搜索(Depth-First-Search)模板

void dfs()//参数用来表示状态  
  
    if(到达终点状态)  
      
        ...//根据需求添加  
        return;  
      
    if(越界或者是不合法状态)  
        return;  
    if(特殊状态)//剪枝,去除一些不需要访问的场景,不一定i俺家
        return ;
    for(扩展方式)  
      
        if(扩展方式所达到状态合法)  
          
            修改操作;//根据题意来添加  
            标记;  
            dfs();  
            (还原标记)//是否还原标记根据题意  
            //如果加上(还原标记)就是 回溯法  
          
      

2、随机字符、数字

	srand((unsigned int )time(0));
	rand()%100+1;//1-100

	char f[52];
    strcpy( f, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
    srand((unsigned)time(0));
	f[rand()%52];//随机字符 

三、复习比赛真题

直接真题从最新往前推,能推多少是多少,这样一来把编程环境也熟悉了,剩下的看造化了。佛祖保佑!

1、模拟题

小明的彩灯
题目描述
小明拥有 N个彩灯,第 i个彩灯的初始亮度为 ai。
小明将进行 Q 次操作,每次操作可选择一段区间,并使区间内彩灯的亮度 +x(x 可能为负数)。
求 Q次操作后每个彩灯的亮度(若彩灯亮度为负数则输出 0)。

输入描述
第一行包含两个正整数 N,Q分别表示彩灯的数量和操作的次数。
第二行包含 N个整数,表示彩灯的初始亮度。
接下来 Q行每行包含一个操作,格式如下:
l r x,表示将区间 l∼r 的彩灯的亮度 +x。
​​
输出描述
输出共 1行,包含 N个整数,表示每个彩灯的亮度。

例:
输入
5 3
2 2 2 1 5
1 3 3
4 5 5
1 1 -100
输出
0 5 5 6 10

题解代码
解1:普通的模拟思维

#include<iostream>

using namespace std;

int main()
        int N,Q; //N个彩灯,Q次操作 
        cin>>N>>Q;
        long long a[N];//第i个灯的亮度a_i 
        for (int i = 0;i < N;i++)
                cin>>a[i];
         
        long long l, r, x;//l-r的区间亮度+x 
        for (int i = 1;i <= Q;i++)//进行模拟操作 
                cin>>l>>r>>x;
                for(int j = l; j <= r; j++)
                        a[j-1] += x;
                
         
        
        for (int i = 0;i < N;i++)//按题目要求输出 
                if (a[i] < 0) 
                        cout<<'0'<<" ";
                else 
                        cout<<a[i]<<" ";
         
        cout<<endl;
        return 0;
       

解2:利用差分数组求解

虽然我承认这个思路确实很妙,而且重要的是学习差分数组以及前缀和的思维,但是不如我解法1来的简单粗暴(嘴硬.jpg)

#include<iostream>

using namespace std;

typedef long long ll;
int main()
        ll N,Q; //N个彩灯,Q次操作 
        cin >> N >> Q;
        ll a[N+1], b[N+1];//第i个灯的亮度a[i-1],b[n]为差分数组 
        a[0] = 0;        b[0] = 0;
        for (int i = 1; i <= N;i++)
                cin >> a[i];
         
        for (int i = 1; i <= N;i++) //构建差分数组 
                b[i] = a[i] - a[i-1];
          
        while(Q--) //模拟操作q次
                int l, r, x;//l-r的区间亮度+x 
                cin >> l >> r >> x;
                b[l] += x;
                b[r + 1] -= x;                
         
        for(int i = 1 ; i <= N ; i ++) //计算前缀和,把差分数组b还原成操作q次后的a数组状态 
                b[i] += b[i - 1];
        for(int i = 1 ; i <= N ; i ++) 
                cout << max(b[i] , 0ll) << " ";//按题目要求输出 
        
        return 0;

2、动态规划题

可曾听闻蓝桥杯又称动态规划杯?这个是重中之中,可以看看我这篇文章:
简单三步法解决动态规划问题

大数相乘问题
数值溢出问题
输出格式问题
日期题可以直接excel

四、其他

先写到这儿吧,稍后边想到啥边补充吧!

参考文章如下,侵必删:

  • https://blog.csdn.net/qq_40838478/article/details/114664223

第十三届蓝桥杯赛前的一点总结

比赛最主要的实现功能,需要关注各个部分之间的逻辑!

赛前的一点总结

LED

整个工程中LED和数码管,按键部分其实是最主要的部分,往年省赛涉及部分也是相对较多的。

  • 点亮L1
sbit L1 = P0^0;
void led_1()

	P2 = (P2 & 0x1f) | 0x80;
		L1 = 0;

  • L1隔0.1s闪烁
#define uchar unsigned char

sbit L1 = P0^0
bit flag_L1;
void Timer0Init(void);		//50毫秒@12.000MHz

void led_1()

	if (flag_L1)
	
		P2 = (P2 & 0x1f) | 0x80;
		L1 = 0;
	
	else 
	
		P2 = (P2 & 0x1f) | 0x80;
		L1 = 1;
	
	


void timer0() interrupt 1

	static uchar i1;
	if (++i1 == 2)
	
		i1 = 0;
		flag_L1 = !flag_L1;
	

void Timer0Init(void)		//50毫秒@12.000MHz

	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xB0;		//设置定时初值
	TH0 = 0x3C;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	
	ET0 = 1;
	EA = 1;


数码管

  • 注意消隐和小数点处理
#define uchar unsigned char
uchar tab[] = 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff  
//0 ~ 9 数码管熄灭
void Delay1ms();		//1ms@12.000MHz,延时1ms用于给足数码管足够显示时间
void dsp_smg_bit1(uchar pos, val, sta)

	P2 = (P2 & 0x1f) | 0x80;
	P0 = 1 << (pos - 1);
	
	P2 = (P2 & 0x1f) | 0x80;
	if (sta)//小数点
		P0 = tab[val] & 0x7f;
	else
		P0 = tab[val];

	Delay1ms();//给足显示时间
	P0 = 0xff;//消隐
	P2 &= 0x1f;

独立按键

  • 先调到BTN模式

正常处理按键

sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;

void key_handle()
	
	if (!S7)
	
		delay_k(15);//灵敏度更高就消抖时间短一些
		if (!S)
		
			whlie(!S)
				display();
			
			ps:这部分处理按键
		
	
	//跟S7实现一样
	if (!S6)
	....
	if (!S5)
		....
	if (!S4)
		....


长按键功能–规定秒数

  • S7长按时间超过1s判断为长按键,否则为短按
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;
#define uint unsigned int
bit pre_flag;//长按键标志,0为判断时间结束,1为判断开始
uint pre_cnt;//计算按下去多久
//这里利用定时器 定时1ms进入中断(ps:当然你也可以定时其他的时间)
void Timer0Init(void)		//1毫秒@12.000MHz

	...

//中断服务函数
void timer0() interrupt 1

	if (pre_flag)//开始判断
	
		pre_cnt++;
	

void key_handle()
	
	if (!S7)
	
		delay_k(15);//灵敏度更高就消抖时间短一些
		if (!S7)
		
			pre_flag = 1;
			whlie(!S7)
				display();
			pre_flag = 0;
		
			if (pre_cnt > 1000)//大于1s
				...长按键操作
			else 
				...短按键操作

			//还有一点重要的是,清零!
			pre_cnt = 0;
		
	
	//跟S7实现一样
	if (!S6)
	....
	if (!S5)
		....
	if (!S4)
		....

长按键功能–不规定秒数

if (!S7)
	
		delay_k(15);//灵敏度更高就消抖时间短一些
		if (!S7)
		
			if (1 == jm)
			
				...界面1的操作
			
			if (2 == jm)//界面2操作长按为显示其他内容,短按或者按完不按处于其他界面
			
				while(!S7)//长按为显示其他内容
					dsp_other();
			
			whlie(!S7)//短按或者按完不按处于其他界面
				display();
		
	

矩阵按键

  • 模式选择KBD

4 * 4 矩阵按键

#define uchar unsigned char

void key_scanf()

	uchar i;
	P44 = P42 = P35 = P34 = 1;//初始化列线拉高
	for (i = 0; i < 4; i++)
	
		P3 |= 0x0f;//行初始化拉高,列线不变
		P3 &= ~(1 << i);//从上往下依次拉低行线
		
		if (!P44)//该行第一个键
			
			delay_k(20);
			if (!P44)
			
				while(!P44)
				
					display();
				
			
			key_val = 4 * i + 1;
			break;
		
		
		剩下三个键类似
	

void key_handle()

	key_scanf();
	通过key_val做出按键处理


2 * 2 矩阵按键

  1. 与4 * 4类似,对应初始化某两条列线先拉高。
  2. 需要for循环就控制i的初始值,不需要就除了需要判断的那一行拉低,另一行拉高,判断拉低的行的两个按键,对应哪一列为低
四个按键对应于左下角四个键s5 s4 s9 s8
void key_handle()

	P32 = P44 = P42 = 1;
	P33 = 0;
	if (!P44)//s4
	
		delay_k(20);
		if (!P44)
		
			while(!P44)
				display();
			
			对应处理按键操作
		
	

斜按键操作

P34 = 1;
	P33 = 0, P30 = 1, P31 = 1, P32 = 1;//其他行默认低电平,所以我们将其拉高
	if(!P34)//s16
	
		delay_k(10);
		if(!P34)
		
			if (2 == jm)
			
				if (--para_temp < 10)//参数操作 + 参数检查
					para_temp = 10;
			
			if (1 == jm)
			
				while(!P34)//s17的长按键操作
				
					rd_time();
					dsp_min_sec();
				
			
			while(!P34)
			
				display();
					
		
	

NE555频率测量

①NE555频率测量,要把跳线帽接在P34和SIGNAL上,使用完之后记得把跳线帽摘下来,不然就会影响矩阵按键,因为矩阵按键第4列也接在P34上
②改变Rb3可以改变输出的频率值

uint cnt_freq, curr_freq;

void timer0() interrupt 1

	cnt_freq++;

void timer1() interrupt 3

	static uchar i1 = 0;
	if (++i1 == 20)//1s
	
		i1 = 0;
		curr_freq = cnt_freq;
		cnt_freq = 0;
	

void sys_init()

	TMOD = 0x04;		//设置定时器模式,定时器0--计数器模式,定时器1--定时器模式
	TL0 = 0xff;
	TH0 = 0xff;//来一个脉冲就溢出计数一次
	TR0 = 1;
	//50ms
	TL1 = 0xB0;		//设置定时初值
	TH1 = 0x3C;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	
	ET0 = 1;
	ET1 = 1;
	EA = 1;



ADC

通过pcf8591读数据,省赛中一般不会太搞人心态的,记住下方模板即可。

  • 从pcf8591读数据
#define uchar unsigned char
uchar rd_pcf8591(uchar addr)

	uchar da;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	
	IIC_SendByte(addr);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	
	da = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
	return da;

需要注意的是,由于pcf8591读取电压读取的为上一次的值,当我们连续从某多个通道读取数据时,每次调用时我们需要读取两次,这样才能保证数据的正确性。

#define uchar unsigned char
float v_val;
uchar rd_pcf8591(uchar addr)

	uchar da;
	uchar i;
	for (i = 0; i < 2; i++)
	
		IIC_Start();
		IIC_SendByte(0x90);
		IIC_WaitAck();
		
		IIC_SendByte(addr);
		IIC_WaitAck();
		
		IIC_Start();
		IIC_SendByte(0x91);
		IIC_WaitAck();
		
		da = IIC_RecByte();
		IIC_SendAck(1);
		IIC_Stop();
		
	return da;

//255.0是小数,整个表达式被强制类型转换为浮点数,最后赋值给浮点数v_val
v_val = rd_pcf8591(0x03) * 5 / 255.0;

DAC

切换成为DAC输出模式,允许 DAC, 使用ADC 通道 0,最后注意需要延时5ms

void dac_pcf8591(uchar da)

	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();

	IIC_SendByte(0x40);  //DAC输出模式,允许 DAC, ADC 通道 0
	IIC_WaitAck();

	IIC_SendByte(da);
	IIC_WaitAck();
	IIC_Stop();
	Delay5ms();

eeprom

省赛中一般就是对eeprom进行读写,也都是固定的代码模块,需要留意的是,为了保证一个完整的写入周期,我们需要延时5ms

  • 写eeprom
#define uchar unsigned char
#define uint unsigned int

void write_eeprom(uchar addr, da)

	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	
	IIC_SendByte(addr);
	IIC_WaitAck();
	
	IIC_SendByte(da);
	IIC_WaitAck();
	IIC_Stop();
	Delay5ms();
	
  • 读eeprom
#define uchar unsigned char
#define uint unsigned int
uchar rd_eeprom(uchar addr)	

	uchar da;
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	
	IIC_SendByte(addr);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	
	da = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
	
	return da;

DS18B20

省赛中一般对温度进行保留小数或者读取整数的操作,也是几乎固定的模板

  • 读取整数
#define uchar unsigned char
uchar rd_temp()

	uchar l, h, t;
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);

	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	l = Read_DS18B20();
	h = Read_DS18B20();
	
	t = (h << 4);
	t |= (l >> 4);
	
	return t;

  • 读取带小数的温度
#define uchar unsigned char
#define uint unsigned int
float rd_temp()

	uchar l, h;
	uint t;
	float temp;
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);

	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	l = Read_DS18B20();
	h = Read_DS18B20();
	
	t = (h & 0x0f);
	t <<= 8;
	t |= l;
	temp = t * 0.0625;
	
	return temp;


DS1302

省赛中一般仅仅使用秒、分、时,使用过程中主要就是需要注意,由于ds1302芯片存储的数据是BCD码,所以我们要进行BCD码与十进制之间的转换,例如0x16 的BCD码为16,十进制为1 * 16 + 6 = 32。
我个人是将这两者之间的转换放到官方给的底层代码中完成的,这样做的好处就是,我们在main.c中,只需要使用十进制,表示时间即可。

  • 读时间
unsigned char Read_Ds1302_Byte ( unsigned char address )

 	unsigned char i,temp=0x00;
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1;	_nop_();
 	Write_Ds1302(address);
 	for (i=0;i<8;i++) 	
 			
		SCK=0;
		temp>>=1;	
 		if(SDA)
 		temp|=0x80;	
 		SCK=1;
	 
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
	SCK=1;	_nop_();
	SDA=0;	_nop_();
	SDA=1;	_nop_();
	temp = temp / 16 * 10 + temp % 16;
	return (temp);			

  • 写时间
void Write_Ds1302_Byte( uns

以上是关于蓝桥杯赛前自救攻略,备赛抱佛脚指南的主要内容,如果未能解决你的问题,请参考以下文章

蓝桥杯新增web应用开发科目—送给想要参赛的小伙伴们一份备赛指南

蓝桥杯新增web应用开发科目—送给想要参赛的小伙伴们一份备赛指南

C/C++蓝桥杯1 备赛准备

《蓝桥杯真题》:2021单片机省赛第二场暨第十三届蓝桥杯赛前模拟试题

蓝桥杯备赛--带你入门树状数组

蓝桥杯备赛--带你入门树状数组