蓝桥杯高频考点(下)
Posted 麻摆子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯高频考点(下)相关的知识,希望对你有一定的参考价值。
一、图论,最短路径问题之朴素dijkstra算法
1.符号定义:共有N个点,找N点到1号点的最短距离;g[N][N]存储每条边的权重;dist[N]存储1号点到每个点的最短距离;st[N]存储每个点的最短路是否已经确定
2.步骤:
(1)先将所有的点到1号点的距离初始化为正无穷;
(2)每次从未标记的节点选择距离出发点最近的节点t并标记st[t]=true;
(3)更新j点到1号点的距离:dist[j] = min(dist[j], dist[t] + g[t][j]);
代码模板:
int g[N][N]; // 存储每条边
int dist[N]; // 存储1号点到每个点的最短距离
bool st[N]; // 存储每个点的最短路是否已经确定
// 求1号点到n号点的最短路,如果不存在则返回-1
int dijkstra()
memset(dist, 0x3f, sizeof dist);//距离dist一开始初始化为无穷大
dist[1] = 0;
for (int i = 0; i < n - 1; i ++ )
int t = -1;// 在未标记(未确定最短路长度)的节点中找距离最小的点t
for (int j = 1; j <= n; j ++ )
if (!st[j] && (t == -1 || dist[t] > dist[j]))//st[j]==false代表j还没确定最短路
t = j;//更新最短路长度的节点
// 用t更新其他点的距离
for (int j = 1; j <= n; j ++ )
dist[j] = min(dist[j], dist[t] + g[t][j]);
st[t] = true;
if (dist[n] == 0x3f3f3f3f) return -1;
return dist[n];
二、图论,最短路径问题之floyd算法
floyd算法有点像DP
代码模板:
初始化:
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
if (i == j) d[i][j] = 0;
else d[i][j] = INF;
// 算法结束后,d[a][b]表示a到b的最短距离
void floyd()
for (int k = 1; k <= n; k ++ )//枚举一个个中间点k,不断更新i到j的距离
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
三、广度优先搜索BFS之迷宫
所谓广度优先,就是每次都尝试访问同一层的节点。 如果同一层都访问完了,再访问下一层。
迷宫问题的模板:(输入是迷宫,输出是最短距离):
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
const int N=110; //n,m的数据范围均为100
int maze[N][N],dis[N][N],n,m; //maze[N][N]用来存储迷宫
//dis[x][y]用来存储(x,y)这一点到坐标原点的距离
queue <pair<int,int>> q;//q队列用来存储宽度优先搜素到的路径也就是走迷宫经过哪些点
int bfs()
memset(dis,-1,sizeof dis); //将dis数组所有元素初始化为-1,表示这个点没有走过
dis[0][0]=0; //位于原点(0,0)到原点的距离为0
q.push(0,0); //将原点入队
int dx[4]=-1,0,1,0,dy[4]=0,1,0,-1; //定义方向向量一共四个方向
while(!q.empty()) //当队列非空时执行循环
auto t=q.front();//取出第一个点
q.pop(); //插入一个位置的同时会弹出一个位置保证循环可以正常终止
for(int i=0;i<4;i++) //遍历四个方向
int x=t.first+dx[i],y=t.second+dy[i]; //四个方向对应x,y坐标
if(x>=0 && x<n && y<m && y>=0 && maze[x][y]==0 && dis[x][y]==-1 )
//x,y都要在迷宫坐标范围内,并且(x,y)不是墙壁且没被走过
dis[x][y]=dis[t.first][t.second]+1; //走到下一个点的同时距离加1
q.push(x,y); //将该点入队尾
return dis[n-1][m-1];//dis[n-1][m-1]是指坐标为(n-1,m-1)的点距离坐标(0,0)的距离
int main()
cin>>n>>m; //输入迷宫的尺寸大小
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
cin>>maze[i][j]; //输入迷宫,比如输入maze[1][1]=0,maze[1][2]=1
cout<<bfs()<<endl; //输出宽度优先搜索结果
return 0;
四、深度优先搜索之DFS
n皇后模板:
#include <iostream>
using namespace std;
const int N = 20;
int n;//棋盘有多少行
char g[N][N];
bool col[N], dg[N], udg[N];//一开始默认为false,即没被用过
void dfs(int row)//表示第row行皇后放在哪
if (row == n)//0到n-1层共n层的棋盘已经排好了
for (int i = 0; i < n; i ++ ) puts(g[i]);
puts("");
return;//退出
for (int i = 0; i < n; i ++ )第row行的皇后可以放在第i列吗
if (!col[i] && !dg[row + i] && !udg[n - row + i])
g[row][i] = 'Q';
col[i] = dg[row + i] = udg[n - row + i] = true;//表示用过
//col=true代表这一列都被标记用过
//dg=true代表副对角线全被标记用过
//udg=true代表主对角线全被标记用过
dfs(row + 1);
//回溯
col[i] = dg[row + i] = udg[n - row + i] = false;
g[row][i] = '.';
int main()
cin >> n;
for (int i = 0; i <n; i ++ )
for (int j = 0; j < n; j ++ )
g[i][j] = '.';//一开始棋盘上面放'.'
dfs(0);
return 0;
第九届蓝桥杯-嵌入式比赛体会与备赛经验
原文地址:http://www.cnblogs.com/NickQ/p/8721317.html
说起蓝桥杯,相信很多电子类的学生,应该很熟悉了吧。。。上周日,我也去湖北工业大学参与了一下。说起这次经历,我还是觉得有点惋惜,但还是觉得应该写出来。
先说比赛体会吧。。
关于考点(湖北工业大学考点), 个人觉得,湖工承办的这次比赛还是比较出色的,但也有以下几点瑕疵。
1、未设带队老师休息点。赛前,我们在赛场外候场时,偶然碰到某个学校的两个带队老师与工作老师询问休息点,才得之此事。
2、比赛环境未准备充分。以嵌入式比赛为例,比赛计算机未为考生准备PDF阅读器,导致部分考生浪费很长时间寻找安装包,安装阅读器环境。而且安装阅读器环境版本较低。其次,部分考生计算机嵌入式开发板的驱动未安装或未安装成功(包括我在内),赛前工作人员未尽到安装和调试的义务。这导致比赛开始后,寻找老师解决问题时,耗费了大量时间。--- 以我为例,我尝试过自己安装驱动,失败后,共计来了3名老师尝试安装驱动,都只是在重复简单的安装步骤,未果后。老师建议换机,但苦于没有空闲机器了。老师尝试重启后,问题才得以解决(注意:比赛过程,考生不允许重启计算机,重启可能会丢失之前数据)。这个过程花费了我将近四十分钟比赛时长(共5小时)。
3、比赛监考设置存在问题。以本赛场为例,有两名学生做监考,且比赛注意事项都由学生朗读,声音小且模糊,导致我们后排附近的考生听不清,带来很多不必要的麻烦,比如提交答案的网址,解压密码等听不清,需要再次单独询问。
以上三点,就是我发现的一些问题,个人认为这是考点未尽到义务的地方。真诚希望湖工以后可以注意下这几点,同时也希望湖工越来越好。。
关于比赛过程
1、 一般是提前20分钟进场,考生检查开发板,示波器是否有明显损坏,检查电脑环境,如解压软件,PDF阅读器,串口驱动和下载器驱动,keil等。 检查提供的资料,是否可用。(快速检查,不然20分钟一般检查不完,当然一般没问题,但有问题的话要及时反映,这一般需要很长时间才能解决。如上所诉)。
2、考场监考员宣读比赛细则,注意事项。考生按考点给的网址,登录考试系统。(如果听不清,一定要要求其讲清楚,不然之后没听清会很麻烦。)
3、阅读考试系统说明,如提交方式等,下载试题。(试题是加密的压缩包)
4、考试开始后,考点给出试题解压密码。(试题是PDF版本的,分客观题和程序题两个文件分开的)
5、作答,并提交答案。(建议先做简答,做完后在考试系统上提交答案,然后在做程序题。答案可提交多次,以最后一次为准。)
6、程序题需要在开发板上有程序,还要按考试系统要求提交源码到考试系统。
注:考试时间以考试系统倒计时为准。。
关于自己
我得承认,我的能力及心态是有问题的。以上指出考点存在的问题并不是掩盖自己的不足。我确实存在很多问题,比如我竟然忘了初始化NVIC优先级,分配TIM优先级等等。所以考完回来,我就一直在检讨,但详细的就不说了。
言归正传,重点说我的心态吧。起初,因为考试系统网址和解压密码听不清,看不清,有点心烦。等平静下来却发现提供的LCD例程无法下载,驱动显示黄色感叹号。多次尝试无果,寻找老师,老师当时不在现场,只能找当时的学生监考,他们表示这需要去找老师,这时心情已经低入谷底。当然期间老师也是换了又换,无法解决,等问题真正解决了,看了时间又觉得时间又不够了。后来也仅实现了部分功能。
当然,解决最后问题的那个老师,也提过要给我补部分比赛时长。被我自己拒绝了,可能是当时心态已蹦,已经想要放弃了吧。事后想想,还确实挺后悔的。
总之,放弃的是自己,后悔的也是自己。心态调整的不好,且不能怨天尤人,只能慢慢从经历中反思,提高自己的能力。。
不管怎么说,我还是参与了,我也和其他同学努力了那么久。关于备赛经验,我想我还是可以提供点参考的。
对于嵌入式的开发板CT117E,还是值得仔细对待的。
关于LED驱动
我想,可能大家都会觉得LED没什么可说的了,只是简单地IO操作。但是我想说,No,这里有个陷阱。而且我觉得如果想参加蓝桥杯嵌入式并用过这个开发板的人,应该都会碰到。
这个问题就是,LED与LCD,PC8-15端口公用的问题。不考虑这个问题的后果就是,LCD和LED同时使用时,如果操作了LCD后,再去控制一个LED,可能会出现没被控制的LED,被莫名其妙的点亮或熄灭。
原因为何?能解决么?怎么解决?
原因:LCD和LED同时使用时,如果操作了LCD后,会导致pc8-15上的电平改变,如果此时控制某个LED灯,更新锁存器,会造成被LCD改变的电平也同步到LED灯造成误触发。
可以解决,解决的原理是,每次更新LED时,将PC8-PC15的引脚状态都更新到合适电平后,再更新锁存器。
提供我自己的代码,方法不止这一种,仅供参考。
1 //LED灯控制函数 2 //注意:第一次调用此函数时,务必需要控制所有灯,即LED_Control(GPIO_Pin_All,0);或 LED_Control(GPIO_Pin_All,1); 3 //原因是:保证LED状态标记变量和当前LED状态同步 4 //LED:被控制LED所连接的STM32引脚,如GPIO_Pin_8,GPIO_Pin_All 5 //LED_Status:新的状态,0:灭 1:亮 6 void LED_Control(uint16_t LED, uint8_t LED_Status) 7 { 8 static u16 temp = 0; //16bit,静态的LED状态标记变量,保存LED的状态 9 10 if(LED_Status == 0) 11 { 12 temp = temp | LED; //更新LED状态标记变量,将某一位值(受控LED对应的)置高电平 13 } 14 else 15 { 16 temp = temp & (~LED); //更新LED状态标记变量,将某一位值(受控LED对应的)置低电平 17 } 18 19 GPIO_Write(GPIOC, temp); //将LED状态标记变量写出,改变LED状态 20 21 GPIO_SetBits(GPIOD, GPIO_Pin_2); 22 GPIO_ResetBits(GPIOD, GPIO_Pin_2); //状态锁存 23 }
关于蜂鸣器
为保证考试环境安静,感觉蜂鸣器一般考试时不会涉及,。但作为一个考点--引脚重映射,也可能会考。
以下三句话就是引脚重映射(注意AFIO时钟使能)
1 GPIO_PinRemapConfig(GPIO_Remap_SWJ_NoJTRST,ENABLE); //PB4 重映射 2 GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE); 3 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
PB4与PA13,PA14,PA15,PB3一样属于SWJ接口IO,有多种分配方式
如下图,任意一种可用的重映射方式都可以。即上述三句,任用其中一句。(注意:SWJ重映射,可能导致下载时需要按一次复位键,才可以)
关于按键
按键例程,写的较为简单,未消都,也不能保证按键次数。
因此,按键例程不具有参考意义。建议理解使用正点原子提供的按键例程方案(只讨论方案,这绝不是广告,资料可免费,免注册在开源电子网下载,http://www.openedv.com/thread-12895-1-1.html)。
原理是:检测到按键按下时,返回一次键值,并置位标志,不在返回有效键值。直到检测到按键被释放后,才会复位标志位,继续下一次按键扫描并返回键值。这样就保证了一次按键按下,只有一次有效键值被返回。
关于uart
串口就是一个简单地外设,配置较为简单。再此只强调已回车结束的接受中断。
1 #define RX_MAX 20 2 extern uint8_t USART_RXBUF[RX_MAX + 1]; //接受数组 3 uint8_t RXOVER = 0; //接受完成标志 4 5 void USART2_IRQHandler(void) 6 { 7 u8 Rx_temp = 0;//临时接受 8 static u8 Rx_ipos = 0; //数组数据位置标志 9 static u8 Rx_flag = 0; //接收到回车(0x0d)等待换行符(0x0a)的标志 10 11 if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //判断中断线 12 { 13 Rx_temp = USART_ReceiveData(USART2); //接受数据 14 USART_ClearITPendingBit(USART2, USART_IT_RXNE); //清中断标志 15 16 if(!Rx_flag) //未接收到回车符 17 { 18 //判断接受的数据是什么 19 if(Rx_temp != 0x0d && Rx_temp != 0x0a) 20 { 21 //普通数据,接受 22 USART_RXBUF[Rx_ipos++] = Rx_temp; 23 } 24 else if(Rx_temp == 0x0d) 25 { 26 //回车符,开始等待换行符以确认结束信号的到来 27 Rx_flag = 1; 28 } 29 else 30 { 31 //换行符,此情况下无回车符,数据不合法,丢弃该帧 32 Rx_ipos = 0; //将位置复位,即丢弃该帧数据 33 } 34 } 35 else if(Rx_temp == 0x0a) 36 { 37 //接收到0x0d的情况下,接受到0x0a,数据正确合法,接受完成 38 USART_RXBUF[Rx_ipos] = \'\\0\'; //加入数组结束符 39 RXOVER = 1;//置位接受完成标志位 40 //等待下一帧数据来临 41 Rx_flag = 0;//恢复等待回车符 42 Rx_ipos = 0;//存储位置复位 43 } 44 else 45 { 46 //接收到0x0d的情况下,却没有接收到0x0a,数据帧不完整,丢弃该帧 47 Rx_flag = 0;//恢复等待回车符 48 Rx_ipos = 0;//存储位置复位 49 } 50 } 51 }
关于x24c02,timer(PWM,捕获),RTC,ADC,DAC,EXIT等考到的知识点,都较为常用,且这部分例程还可以。再次不在展开了。
有不理解或想了解其他的,请留言。。。此贴完
以上是关于蓝桥杯高频考点(下)的主要内容,如果未能解决你的问题,请参考以下文章