D. Constructing the Array

题目:http://codeforces.com/contest/1353/problem/D
题意:对于给定的数字,找到一个数组使:
1、选择最大的长度子数组(连续子段)由只在所有这样的段中,选择最左边一个;
2、让这段[l;r][l;r]。如果r−l+1r−l+1是奇数(不能被22)然后分配(集合)a[l+r2]:=ia[l+r2]:=i(在哪里ii为当前操作的编号),则为(如果为r−l+1r−l+1是偶数)赋值(集)a[l+r−12]:=ia[l+r−12]:=i.

思路:对于该题想到的可以使用二叉树进行查找,但是一直没想到咋写弄,看了别人的代码有的人用了PriorityQueue这个API,然后查下发现内部本身是个二叉树,但是还是不是特别懂,

PriorityQueue内部结构方法讲解:https://blog.csdn.net/u013309870/article/details/71189189

AC代码:

package 练习;
import java.io.*;
import java.math.*;
import java.math.BigInteger;
import java.util.*;
public class 练习 {
 public static void main (String[] args) {
  Scanner sc=new Scanner(System.in);
         int t = sc.nextInt();
         while (t-- > 0) {
             int n = sc.nextInt();
             int k = 1;
             int[] arr = new int[n];
             PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> {//重写,划分的条件,得到题中的两个数的数组
                 int len1 = a[1]-a[0]+1, len2 = b[1]-b[0]+1;
                 if (len1 != len2) return (len2-len1); 
                 return (a[0]-b[0]);});
  
             pq.add(new int[]{0, n-1});//直接划分得到想要的结果
             while (!pq.isEmpty()) {//pq不为空时
                 int[] cur = pq.poll();//检索并删除此队列的头                 
                 int len = cur[1] - cur[0] + 1;
                 int mid = (cur[1]+cur[0])/2;//获得下标
                 arr[mid] = k++;
                 if (len == 1) continue;//len为1时没有了
                 if ((mid-1) >= cur[0])
                     pq.offer(new int[]{cur[0], mid-1});
                 if ((mid+1) <= cur[1])
                     pq.offer(new int[]{mid+1, cur[1]});
             }
             for (int elem: arr) System.out.print(elem + " " );
             System.out.println();
         }
     }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值