小米OJ之倔强青铜

不一样的排序

  • 描述:现在有 n 个数,需要用因子个数的多少进行排序,因子个数多的排在后面,因子个数少的排在前面,如果因子个数相同那么就比较这个数的大小,数大的放在后面,数小的放在前面。现在让你说出排序之后第 K 个位置的数字是多少。
  • 输入:
    第 1 个整数为整数 K,1 ≤K ≤ 10^6 ;
    第 2 个为整数 n,表示数字的数量,n<10^7;
    接下来有 n 个整数,每个数的大小不超过 10^6 。
  • 输出:输出排序之后的第 K 位置的数值。
  • 输入样例:4 6 1 2 3 4 5 6; 1 2 3 4 5 6按因子个数排序后是:1 2 3 5 4 6
  • 输出样例:5
  • 难度:☆☆两颗星
      
      这道题双列集合TreeMap<>,因为该集合的构造函数中可以自定义比较器Comparator,根据自定义比较器确定元素的排序。首先,需要自定义一个函数计算每个数字的因子个数,然后将数字作为Key,因子个数作为Value存入集合中,根据自定义的比较器,元素的排序是按照题中规则进行排序的。因此,只要找出集合中第K个元素的Key,并将其输出。整个程序运行时间稍微的有点长花了2.07 s。ps:我也很无奈,回头再改进,试试stream流和函数式接口来操作。
import java.util.*;

public class Main {
    public static void main(String args[]) {
        /*
        	自定义比较器,根据因子数的个数进行排序
        */
      Scanner scan = new Scanner(System.in);
        String line;
        while (scan.hasNextLine()) {
            line = scan.nextLine().trim();
            String[] arr = line.split(" ");
            int[] intArr = new int[arr.length-2];
            
            TreeMap<Integer, Integer> tm = new TreeMap<>(new Comparator<Integer>() {

        		@Override
        		public int compare(Integer key1, Integer key2) {
        			return count(key1) - count(key2) == 0 ? key1 - key2 :count(key1) - count(key2);
        		}
        		
        	});
          
            for (int i = 0; i < arr.length -2; i++) {
				intArr[i] = Integer.parseInt(arr[i+2]);
				tm.put(intArr[i], count(intArr[i]));
			} 
            
            //System.out.println(tm);
            
            int pos = Integer.parseInt(arr[0]) - 1;
            int cnt = 0;
            for (Integer key : tm.keySet()) {
				if(cnt == pos) {
					System.out.println(key);
					return;
				}
				cnt++;
			}
            
            
        }

	}
    
    public static int count(int n){
        int s = 1;
        for(int i = 2; i * i <= n; i++){
            if(n % i == 0){ 
                int a = 0;
                while(n % i == 0){
                    n /= i;
                    a++;
                }
                s = s * (a + 1);
            }
        }
        if(n > 1) s = s * 2;
        return s;
    }

}
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值