蓝桥杯 ADV-205 算法提高 拿糖果(动态规划)

问题描述
妈妈给小B买了N块糖!但是她不允许小B直接吃掉。
  假设当前有M块糖,小B每次可以拿P块糖,其中P是M的一个不大于根号下M的质因数。这时,妈妈就会在小B拿了P块糖以后再从糖堆里拿走P块糖。然后小B就可以接着拿糖。
  现在小B希望知道最多可以拿多少糖。
输入格式
  一个整数N
输出格式
  最多可以拿多少糖
样例输入
15
样例输出
6
数据规模和约定
N <= 100000

分析:动态规划问题~~首先呢~创建一个满足不大于根号下最大值MAXN的素数表,然后对素数表里面的数逐个遍历~
构建一个dp[i]数组,表示当糖果数量为i的时候所能拿的最多的糖果数量~
对于dp[i]的值:因为小B只能每次拿不大于根号下i的质因数,遍历素数表中满足条件的素数(prime[j] <= sqrt(i) && i % prime[j] == 0),更新dp[i]的值为(dp[i-2*prime[j]] + prime[j])的最大值~
即:dp[i] = max(dp[i], dp[i-2*prime[j]] + prime[j]);

 

蓝桥杯 ADV-143 算法提高 扶老奶奶过街

一共有5个红领巾,编号分别为A、B、C、D、E,老奶奶被他们其中一个扶过了马路。
五个红领巾各自说话:
A :我和E都没有扶老奶奶
B :老奶奶是被C和E其中一个扶过大街的
C :老奶奶是被我和D其中一个扶过大街的
D :B和C都没有扶老奶奶过街
E :我没有扶老奶奶
已知五个红领巾中有且只有2个人说的是真话,请问是谁扶这老奶奶过了街?
若有多个答案,在一行中输出,编号之间用空格隔开。
例如
A B C D E(这显然不是正确答案)

分析:建立一个含有5个元素的数组,分别代表abcde五个人。逐个假设abcde是扶老奶奶过街的人,判断他们说话为真的个数是否为2,为2的时候输出

 

蓝桥杯 ADV-108 算法提高 分数统计

问题描述
  2016.4.5已更新此题,此前的程序需要重新提交。
问题描述
  给定一个百分制成绩T,将其划分为如下五个等级之一:
  90~100为A,80~89为B,70~79为C,60~69为D,0~59为E
  现在给定一个文件inp,文件中包含若干百分制成绩(成绩个数不超过100),请你统计五个等级段的人数,并找出人数最多的那个等级段,按照从大到小的顺序输出该段中所有人成绩(保证人数最多的等级只有一个)。要求输出到指定文件oup中。
输入格式
  若干0~100的正整数,用空格隔开
输出格式
  第一行为5个正整数,分别表示A,B,C,D,E五个等级段的人数
  第二行一个正整数,表示人数最多的等级段中人数
  接下来一行若干个用空格隔开的正整数,表示人数最多的那个等级中所有人的分数,按从大到小的顺序输出。
样例输入
100 80 85 77 55 61 82 90 71 60
样例输出
2 3 2 2 1
3
85 82 80
分析:它赖皮。。测试数据里面有分数的个数的值。。而测试样例里面没写。。。

 

蓝桥杯 ADV-104 算法提高 打水问题

问题描述
  N个人要打水,有M个水龙头,第i个人打水所需时间为Ti,请安排一个合理的方案使得所有人的等待时间之和尽量小。
输入格式
  第一行两个正整数N M 接下来一行N个正整数Ti。
  N,M<=1000,Ti<=1000
输出格式
  最小的等待时间之和。(不需要输出具体的安排方案)
样例输入
7 3
3 6 1 4 2 5 7
样例输出
11
提示
  一种最佳打水方案是,将N个人按照Ti从小到大的顺序依次分配到M个龙头打水。
  例如样例中,Ti从小到大排序为1,2,3,4,5,6,7,将他们依次分配到3个龙头,则去龙头一打水的为1,4,7;去龙头二打水的为2,5;去第三个龙头打水的为3,6。
  第一个龙头打水的人总等待时间 = 0 + 1 + (1 + 4) = 6
  第二个龙头打水的人总等待时间 = 0 + 2 = 2
  第三个龙头打水的人总等待时间 = 0 + 3 = 3
  所以总的等待时间 = 6 + 2 + 3 = 11

 

蓝桥杯 ADV-83 算法提高 寻找三位数

问题描述
  将1,2,…,9共9个数分成三组,分别组成三个三位数,且使这三个三位数构成
  1:2:3的比例,试求出所有满足条件的三个三位数。
  例如:三个三位数192,384,576满足以上条件。
输入格式
  无输入文件
输出格式
  输出每行有三个数,为满足题设三位数。各行为满足要求的不同解。
分析:先确定第一个数字,然后判断这个数字的两倍数和三倍数是否满足条件~用book数组标记当前数字是否已经出现过~

 

【最短路径】:Dijkstra算法、SPFA算法、Bellman-Ford算法和Floyd-Warshall算法

求最短路径最常用的算法有:
Dijkstra算法、SPFA算法、Bellman-Ford算法和Floyd-Warshall算法。
Dijkstra算法、SPFA算法、Bellman-Ford算法这三个求单源最短路径,最后一个Floyd-Warshall算法可以求全局最短路径也可以求单源路径,效率比较低。
SPFA算法是Bellman算法的队列优化
Dijkstra算法不能求带负权边的最短路径,而SPFA算法、Bellman-Ford算法、Floyd-Warshall可以求带负权边的最短路径。
Bellman-Ford算法的核心代码只有4行,Floyd-Warshall算法的核心代码只有5行。

1.最基本的求单源最短路径方法是图的深度优先遍历
用 min = 99999999 记录路径的最小值,book[i]标记结点 i 是否被访问过~

2.单源最短路径:Dijkstra算法
dis[i]是需要不断更新的数组,它表示当前结点1(源点)到其余各结点的最短路径长度~
book[i]标记当前结点最短路径是确定值还是估计值~
算法实现的过程是:每次找到离结点1最近的那个点,然后以该结点为中心扩展,最终得到源点到所有点的最短路径~~每次新扩展一个距离最短的点,更新与其相邻的点的距离。当所有边权都为正时,由于不会存在一个距离更短的没扩展过的点,所以这个点的距离永远不会再被改变,因而保证了算法的正确性。不过根据这个原理,用Dijkstra求最短路的图不能有负权边,因为扩展到负权边的时候会产生更短的距离,有可能就破坏了已经更新的点距离不会改变的性质~~
找到所有估计值当中最小的值min以及它的结点u,然后把该结点u标记为确定值,通过这个确定值为中转点更新别的所有值的最短路径(松弛别的两个顶点连接的边)

3.Bellman-Ford算法——解决负权边
算法思想:对所有的边进行n-1次“松弛”操作

4.Bellman-Ford的队列优化(SPFA算法)
每次选取首顶点u,对u的所有出边进行松弛操作~如果有一条u->v的边,通过这条边使得源点到顶点v的路程变短,且顶点v不在当前队列中,就把这个顶点v放入队尾。同一个顶点在队列中出现多次是毫无意义的,所以用一个数组来判重复,判断哪些点已经在队列中。对顶点u的所有出边都松弛完毕后,就将顶点v出队~