hdu5493

有n个人,每个人的身高和左边或右边比自己高的人的个数num[i],输出符合给出的条件且字典序最小的从左到右队列里每个人的身高。
先按身高从小到大排个序,考虑第i个人前面留的位置肯定是num[i]或n-i-num[i]中的较小值,这样才能让字典序最小,一旦有n - i - num[i]的值小于0说明无解。

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NavigableSet;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeSet;

public class Main {

    public static void main(String[] args) throws IOException{

           StreamTokenizer cin = new StreamTokenizer(new BufferedInputStream(System.in)); 
           InputReader in = new InputReader(System.in)  ;
           PrintWriter out = new PrintWriter(System.out) ;  

           int t = in.nextInt() ;
           for(int cas = 1 ; cas <= t ; cas++){
                 out.print("Case #" + cas + ":") ;
                 new Task().solve(in, out) ;
           }

           out.flush() ;

    }

}

class  Task{
       static  int  N = 100008 ;
       static  int[] sum = new int[N<<2] ;
       static  int[] ans = new int[N] ;

       void  make(int l , int r , int root){
             sum[root] = r - l + 1 ;
             if(l == r) return ;
             int m = (l + r) >> 1 ;
             make(l, m, root<<1) ;
             make(m+1 , r, root<<1|1) ;
       }

       void  update(int k , int h , int l , int r , int root){
             sum[root]-- ;
             if(l == r){
                    ans[l] = h ;
                    return ;
             }
             int m = (l + r) >> 1 ;
             if(sum[root<<1] > k) update(k, h, l, m, root<<1) ;
             else update(k-sum[root<<1] , h, m+1, r, root<<1|1) ;
       }

       static  class  Person implements Comparable<Person>{
               int   high ;
               int   num  ;

               public int compareTo(Person o) {
                       return Integer.compare(high, o.high)   ;
               } 

               public Person(int _high , int _num){
                       this.high = _high ; 
                       this.num = _num ;
                }
       }

       static  Person[] p  = new Person[N] ;

       void   solve(InputReader in , PrintWriter out){
              int n = in.nextInt()  ;
              for(int i = 1 ; i <= n ; i++)  p[i] = new Person(in.nextInt(), in.nextInt()) ;
              Arrays.sort(p , 1 , 1+n) ;

              make(1, n, 1);

              boolean  impossible = false  ;
              for(int i = 1 ; i <= n ; i++){
                    if(impossible) continue ;
                    int k = Math.min(p[i].num , n-i-p[i].num) ;
                    if(k < 0){
                           impossible =  true ;
                           break ;
                    }
                    update(k, p[i].high, 1, n, 1) ;
              }

              if(impossible) out.println(" impossible");
              else{
                    for(int i = 1 ; i <= n ; i++) out.print(" " + ans[i]) ;
                    out.println() ;
              }
       }
} 

class   InputReader{
        public BufferedReader  reader;
        public StringTokenizer  tokenizer;

        public InputReader(InputStream stream){
               reader = new BufferedReader(new InputStreamReader(stream), 32768) ;
               tokenizer = null ;
        }

        public String next(){
               while(tokenizer == null || ! tokenizer.hasMoreTokens()){
                        try{
                            tokenizer = new StringTokenizer(reader.readLine());
                        }catch (IOException e) {
                             throw new RuntimeException(e);
                        }
               }
               return tokenizer.nextToken();  
        }

        public int  nextInt(){
                    return Integer.parseInt(next());
        }

        public long nextLong(){
                    return Long.parseLong(next());
        }

        public double nextDouble(){
                    return  Double.parseDouble(next());
        }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值