zoukankan      html  css  js  c++  java
  • Week4 C-TT的神秘礼物

    题目大意:

    TT 是一位重度爱猫人士,每日沉溺于 B 站上的猫咪频道。

    有一天,TT 的好友 ZJM 决定交给 TT 一个难题,如果 TT 能够解决这个难题,ZJM 就会买一只可爱猫咪送给 TT。

    任务内容是,给定一个 N 个数的数组 cat[i],并用这个数组生成一个新数组 ans[i]。新数组定义为对于任意的 i, j 且 i != j,均有 ans[] = abs(cat[i] - cat[j]),1 <= i < j <= N。试求出这个新数组的中位数,中位数即为排序之后 (len+1)/2 位置对应的数字,'/' 为下取整。

    TT 非常想得到那只可爱的猫咪,你能帮帮他吗?

    Input

    多组输入,每次输入一个 N,表示有 N 个数,之后输入一个长度为 N 的序列 cat, cat[i] <= 1e9 , 3 <= n <= 1e5

    Output

    输出新数组 ans 的中位数

    Sample Input

    4
    1 3 2 4
    3
    1 10 2
    

    Sample Output

    1
    8

    思路:两次二分-淋漓尽致

    这道题目知道是用二分的思想做,但是做的时候却卡了好几天,怎么二分呢?
    这个时候就要回到中位数的定义中去:大小排序后最中间位置,即(n*(n-1)/2+1)/2
    新数组中最大数为原数组中最大数与最小数之差,然后可以对这个值二分。要判断其在新数组中的位置,即找在新数组中有多少比他大或小。
    这一步又要用到二分的思想,对于固定的数,找满足条件的数的个数(原数组二分 找满足差的个数 )
     1 /*
     2     Name: 
     3     Copyright: 
     4     Author:sduAllen 
     5     Date: 19/03/20 11:44
     6     Description: 
     7 */
     8 
     9 #include<iostream>
    10 #include<stdio.h>
    11 #include<algorithm>
    12 #include<cmath>
    13 using namespace std;
    14 
    15 //const int max = 1e5+1;
    16 int *cat = new int[100001];
    17 int N;
    18 int last_index(int start){ //找到最后一个满足小于等于start的位置索引 
    19     int l=0,r=N-1,index=-1;
    20     while(l<=r){
    21         int mid = (l+r)/2;
    22         if(cat[mid]<=start){
    23             index=mid;
    24             l=mid+1;
    25         }
    26         else
    27             r=mid-1;
    28     }
    29     return index;
    30 }
    31 
    32 int main(){ 
    33     
    34     while(scanf("%d",&N)!= EOF){
    35         for(int i=0;i<N;i++)
    36         scanf("%d",&cat[i]);
    37         sort(cat,cat+N);
    38         
    39         int ans_Mid = (N*(N-1)/2+1)/2; 
    40         int themid;
    41         int l=0,r=cat[N-1]-cat[0];    //新数组的最大最小值    
    42     
    43         while(l<=r){   //在0~max之间二分 
    44             int cnt = 0,mid = (l+r)/2;    //cnt计算在新数组中的位置 
    45             for(int i=0;i<N;i++){
    46                 int index = last_index(cat[i]+mid);
    47                 if(index!=-1)
    48                 cnt += index-i;
    49             }
    50             if(cnt >= ans_Mid){
    51                 themid = mid;
    52                 r=mid-1;
    53             }
    54             else
    55                 l=mid+1;
    56         }
    57         printf("%d
    ",themid);        
    58     }
    59     return 0;    
    60 }



    流转星云
  • 相关阅读:
    刚刚开通
    腾讯面试经历2015
    排序之归并排序
    AC自动机
    后缀数组初步
    概率dp初探
    【NOIP2015】反思+题解
    Built-in functions
    poj2528 Mayor's posters(线段树区间覆盖)
    Codeforces #317 C.Lengthening Sticks(数学)
  • 原文地址:https://www.cnblogs.com/liuzhuan-xingyun/p/12529698.html
Copyright © 2011-2022 走看看