将一系列给定数字插入一个初始为空的小顶堆H[]
。随后对任意给定的下标i
,打印从H[i]
到根结点的路径。
输入格式:
每组测试第1行包含2个正整数NNN和MMM(≤1000\le 1000≤1000),分别是插入元素的个数、以及需要打印的路径条数。下一行给出区间[-10000, 10000]内的NNN个要被插入一个初始为空的小顶堆的整数。最后一行给出MMM个下标。
输出格式:
对输入中给出的每个下标i
,在一行中输出从H[i]
到根结点的路径上的数据。数字间以1个空格分隔,行末不得有多余空格。
输入样例:
5 3
46 23 26 24 10
5 4 3
输出样例:
24 23 10 46 23 10 26 10 这个涉及到最小堆的调整问题, 方法
一:每输入一个数,就调整一次 方法二:全部输入完在对最小堆进行调整. 方法一代码:(这个方法用java超时,用G++不会超时)
import java.util.Scanner; public class Main{ private static int[] nums = new int[1005]; public static void main(String[] args) { Scanner scan = new Scanner(System.in); int N = scan.nextInt(); int M = scan.nextInt(); int[] v = new int[M]; int[] vv = new int[N+1]; for(int i=1;i<=N;i++){ nums[i] = scan.nextInt(); //调整最小堆 adjust(i); } for(int i=0;i<M;i++){ int temp = scan.nextInt(); v[i]=temp; } //将调整后的最小堆放在新的数组vv中 // for(int i=1;i<=N;i++){ // vv[i]=nums[i]; // } //输出结果 for(int i=0;i<M;i++){ String str = ""; int k = v[i]; while(k>0){ str += nums[k]+" "; k/=2; } System.out.println(str.trim()); } } //每输入一个数就对最小堆进行调整 public static void adjust(int k){ while(k!=1){ int ka = k/2; if(nums[k]<nums[ka]){ int temp = nums[k]; nums[k] = nums[ka]; nums[ka] = temp; } k = ka; } } }