1、第7单元第6课 队列的应用,信息学奥赛培训之数据结构,例1、Blah数集(blah,1s,256MB),数学家高斯小时候偶然间发现一种有趣的自然数集合Blah,对于以a为基的集合Ba定义如下: (1) a是集合Ba的基,且a是Ba的第一个元素; (2)如果x在集合Ba中,则2x+1和3x+1也都在集合Ba中; (3)没有其他元素在集合Ba中了。 现在小高斯想知道如果将集合Ba中元素按照升序排列,第N个元素会是多少?注意:集合中没有重复的元素。 输入格式: 1行,两个正整数,分别表示集合的基a(1=a=50)以及所求元素序号n(1=n=1000000). 输出格式: 1行,1个正整数,表示集合B
2、lah的第n个元素值. 输入样例1: 1 100 输出样例1: 418 输入样例2: 28 5437 输出样例2: 900585,问题分析:,根据条件,除了第一个数a以外,可以把数集q的所有数分成两个子集,一个是用2x+1来表示的数的集合1,另一个是用3x+1来表示的数的集合2,两个集合要保持有序非常容易,只需用两个指针two和three来记录。其中two表示集合1下一个要产生的数是由qtwo*2+1得到,three表示集合2下一个要产生的数是由qthree*3+1得到。接下来比较qtwo*2+1和qthree*3+1的大小关系: 1)如果qtwo*2+1qthree*3+1,则把qthree
3、*3+1加入到数集中。 3)如果qtwo*2+1qthree*3+1,则取任意一个加入数集中即可。 所以,本题就是利用队列先进先去的特点,模拟n个数依次产生的过程。,例2、关系网络(relationship,1s,256MB),问题描述: 有n个人,他们的编号为1n,其中有一些人相互认识,现在x想要认识y,可以通过他所认识的人来认识更多的人(如果a认识b,b认识c,那么a可以通过b来认识c),求出x最少需要通过多少人才能认识y。 输入格式: 第1行3个整数n、x、y,2=n=100; 接下来的n行是一个n*n的邻接矩阵,aij=1表示i认识j,aij=0表示不认识。保证i=j时,aij=0,并
4、且aij=aji。 输出格式: 1行,一个整数,表示x认识y最少需要通过的人数。数据保证x一定能认识y。,输入样例: 5 1 5 0 1 0 0 0 1 0 1 1 0 0 1 0 1 0 0 1 1 0 1 0 0 0 1 0输出样例: 2,问题分析:,本题是最优值问题。显然,如果x和y本身就认识,则答案是0;否则,答案至少为1.如果x和y通过z这一个人就间接认识,那么答案是1,可以通过穷举z来实现;否则,答案至少为2.如此做下去,一定能找到答案(最大为n-2).这种算法叫作“广度优先搜索”,简称“广搜”,具体实现需要通过一个队列在实现过程中扩展到所有人。 把x加入队列并设置为队首元素,设q
5、x1=0,从队首开始进行广搜,穷举邻接矩阵的第x行,看x认识谁(判断axj=1),认识的人(j)全部依次入队,并且qj1+.如果出现了y,则输出qf1-1,结束搜索;否则,取出队首元素继续广搜。,例3、图的广度优先遍历。(graph_bfs,1s,256MB),问题描述: 读入一个用邻接矩阵存储的无向图,输出它的广度优先遍历序列。 输入格式: 第1行1个正整数n,表示图中顶点数,2=n=100; 接下来的n行是一个n*n的邻接矩阵,aij=1表示顶点i和顶点j之间有直接边相连, aij=0表示没有直接边相连。保证i=j时,aij=0,并且aij=aji。 输出格式: 输出1n的某一排列,表示从
6、顶点1开始,对该图进行广度优先遍历得到的顶点序列,每两个数之间用一个”-”分隔。,输入样例: 8 0 1 1 0 0 0 0 0 1 0 0 1 1 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 1 0输出样例: 1-2-3-4-5-7-8-6,问题分析:,图7.6-1所示为图的广宽优先遍历。用队列来实现图的广度优先遍历:先从某个顶点出发,把这个顶点入队,作为队首元素。然后把跟队首元素相连的顶点再依次入队,最后队首元素出队。接着再把新的队首元素相
7、连的所有顶点入队,新的队首元素出队。如此下去,直到所有元素都出队,出队的顺序就是图的广度优先遍历序列。,练习1:猴群(monkey,1s,256MB),问题描述: 给出一个由数字09组成的矩形,其中数字0代表树,19代表猴子,凡是由0或矩形边围起来的区域表示有一群猴子在这一带。编程求矩形中有多少群猴子。 输入格式: 第1行两个正整数,表示矩形的行数m和列数n,1=m,n=100; 下面为一个m*n的数字矩形。 输出格式: 1行,一个数,表示猴群的数目。,输入样例: 4 10 0234500067 1034560500 2045600671 0000000089输出样例: 4,练习2:魔法师与扑
8、克牌游戏(magic,1s,256MB),问题描述: 魔法师在玩一种扑克牌游戏,n张扑克分别记上1,2,n。他打开第一张是1,把它放在一边。然后把最上面的两张一张一张地依次移到最后,打开上面一张刚好是2,再放在一边;然后把上面的3张一张一张移到最后,打开上面一张刚好是3,再放到一边;如此重复下去,直到打开最后一张是n,放在一边,这时他发现,放在一边的扑克刚好是1,2,n这样排列的。请编程输出这些扑克原来是怎么排列的。 输入格式:1行,一个正整数n。 输出格式:1行,n个正整数,表示这些扑克牌原来的排列顺序,每两个数之间有一个空格。,输入样例1: 5 输出样例1: 1 4 5 2 3 输入样例2
9、: 9 输出样例2: 1 8 6 2 9 4 5 3 7 数据范围: 对于70%的数据:n=100。 对于100%的数据:n=10000.,练习3:奇怪的电梯。(lift,1s,256MB),问题描述: 假设一栋大楼有一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第i层楼(1=i=N)上有一个数字ki(0=ki=N)。电梯只有4个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如,3 3 1 2 5代表了ki(k1=3,k2=3,),从一层开始。在一层,按“上”可以到4层,按“下”是不起作用的,因为没有2层。那么,从A层到B层至少要按
10、几次按钮呢?,输入格式: 第1行为3个正整数,表示N,A和B,1=N=200,1=A,B=N; 第2行为N个正整数,表示ki。 输出格式: 1行,一个数,即最少按键次数。若无法到达,则输出1. 输入样例: 5 1 5 3 3 1 2 5 输出样例: 3,练习4:棋盘(chess,1s,256MB)noip2017t3,【问题描述】 有一个m m的棋盘,棋盘上每一个格子可能是红色、黄色或没有任何颜色的。你现在要从棋盘的最左上角走到棋盘的最右下角。任何一个时刻,你所站在的位置必须是有颜色的(不能是无色的) ,你只能向上、下、左、右四个方向前进。当你从一个格子走向另一个格子时,如果两个格子的颜色相同
11、,那你不需要花费金币;如果不同,则你需要花费 1 个金币。另外, 你可以花费 2 个金币施展魔法让下一个无色格子暂时变为你指定的颜色。 但这个魔法不能连续使用,而且这个魔法的持续时间很短,也就是说,如果你使用了这个魔法,走到了这个暂时有颜色的格子上,你就不能继续使用魔法;只有当你离开这个位置,走到一个本来就有颜色的格子上的时候,你才能继续使用这个魔法,而当你离开了这个位置(施展魔法使得变为有颜色的格子)时,这个格子恢复为无色。现在你要从棋盘的最左上角,走到棋盘的最右下角,求花费的最少金币是多少?,【输入格式】 输入文件名为 chess.in。 数据的第一行包含两个正整数 m,n,以一个空格分开
12、,分别代表棋盘的大小,棋盘上有颜色的格子的数量。接下来的 n 行,每行三个正整数 x,y,c,分别表示坐标为(x,y)的格子有颜色 c。其中 c=1 代表黄色,c=0 代表红色。 相邻两个数之间用一个空格隔开。 棋盘左上角的坐标为(1, 1) ,右下角的坐标为(m, m) 。棋盘上其余的格子都是无色。保证棋盘的左上角,也就是(1,1)一定是有颜色的。 【输出格式】 输出文件名为 chess.out。 输出一行,一个整数,表示花费的金币的最小值,如果无法到达,输出-1。,【输入输出样例 1】 chess.in 5 7 1 1 0 1 2 0 2 2 1 3 3 1 3 4 0 4 4 1 5 5
13、 0 chess.out 8,【输入输出样例 1 说明】 从(1,1)开始,走到(1,2)不花费金币 从(1,2)向下走到(2,2)花费 1 枚金币 从(2,2)施展魔法,将(2,3)变为黄色,花费 2 枚金币 从(2,2)走到(2,3)不花费金币 从(2,3)走到(3,3)不花费金币 从(3,3)走到(3,4)花费 1 枚金币 从(3,4)走到(4,4)花费 1 枚金币 从(4,4)施展魔法,将(4,5)变为黄色,花费 2 枚金币, 从(4,4)走到(4,5)不花费金币 从(4,5)走到(5,5)花费 1 枚金币 共花费 8 枚金币。,【输入输出样例 2】 chess.in 5 5 1 1
14、0 1 2 0 2 2 1 3 3 1 5 5 0 chess.out -1,【输入输出样例 2 说明】 从(1,1)走到(1,2) ,不花费金币 从(1,2)走到(2,2) ,花费 1 金币 施展魔法将(2,3)变为黄色,并从(2,2)走到(2,3)花费 2 金币 从(2,3)走到(3,3)不花费金币 从(3,3)只能施展魔法到达(3,2) , (2,3) , (3,4) , (4,3) 而从以上四点均无法到达(5,5) ,故无法到达终点,输出1,【数据规模与约定】 对于 30%的数据,1 m 5, 1 n 10。 对于 60%的数据,1 m 20, 1 n 200。 对于 100%的数据,1 m 100, 1 n 1,000。,