题目: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();
}
}
}