zoukankan      html  css  js  c++  java
  • Codeforces 1301B Motarack's Birthday(二分)

    题目链接:http://codeforces.com/problemset/problem/1301/B

    思路:

    (1)都是-1的情况

    (2)只有一个除-1之外的数

    (3)至少有两个除-1之外的不同的数字

    对于(3),我们可以得出最大数字和最小数字_max,_min,而我们的答案m和k易得一定是在[_max,_min]中得出,

    那么我们当然可以初始化m = (_max-_min)。因为数据范围大,我们可以通过二分来处理这个答案。

    我们可以二分mid ∈[L=_min,R=_max],枚举k,然后把k带入原数组,覆盖-1,在这个k的情况下,tmp_m最大是多少,

    并且记录tmp_m最大的时候,两个坐标,dx,dy。为什么要记录两个坐标呢,因为我们不知道怎么二分才是最优的,

    而我们可以想到,在一个一维坐标上,(x-----------mid--------y),“--"表示距离,dis(max(mid-x,y-mid)) = m,我们想的是

    可不可以让m变小,那么我们可以让这个距离尽可能的平分,那么m就最小了。

    显然:如果tmp_m<m那么更新m = tmp_m,k = mid。

    这里有一种特殊情况(  -1 -1 -1 40 35 -1 35 ),m = (_max-_min)就是答案,所以一开始对k也要初始化一下,显然k = _max or _min都可。

     1 #include <iostream>
     2 #include <string>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <cmath>
     6 using namespace std;
     7 
     8 const int N = (int)2e5+100,inf = (int)1e9+100;
     9 int a[N];
    10 int m,k,l,r,n,mid;
    11 
    12 void fun(int mid){
    13     int dx,dy,inx_x,inx_y,tmp_m = -1;
    14     for(int i = 1; i < n; ++i){
    15         if(a[i-1] == -1 && a[i] == -1) continue;
    16         dy = a[i] == -1? mid : a[i];
    17         dx = a[i-1] == -1? mid : a[i-1];
    18         if(abs(dx-dy) > tmp_m){//tmp_m最大化
    19             tmp_m = abs(dx-dy);
    20             inx_x = i-1; inx_y = i;//坐标
    21         }
    22     }
    23     int v = a[inx_x] == -1 ? a[inx_y] : a[inx_x];
    24     if(v >= mid) l = mid + 1;// x-------mid-----------v
    25     else r = mid - 1;       //  v-----------mid------x
    26 
    27     if(tmp_m < m){//m最小化
    28         m = tmp_m; k = mid;
    29     }
    30 }
    31 
    32 int main(){
    33 
    34     ios::sync_with_stdio(false);
    35     cin.tie(0); cout.tie(0);
    36 
    37     int T;
    38     cin >> T;
    39     while(T--){
    40         cin >> n;
    41         int _min = inf,_max = -1;
    42         for(int i = 0; i < n; ++i){
    43             cin >> a[i];
    44             if(a[i] == -1) continue;
    45             _min = min(_min,a[i]);
    46             _max = max(_max,a[i]);
    47         }
    48 
    49         if(_min == inf && _max == -1) cout << 0 << " " << 0 << endl;
    50         else if(_max == _min) cout << 0 << " " << _min << endl;
    51         else{
    52             l = _min,r = _max,mid,k = _min;
    53             m = r-l;
    54             while(l <= r){
    55                 mid = (l+r)>>1;
    56                 fun(mid);
    57             }
    58             cout << m << " " << k << endl;
    59         }
    60     }
    61 
    62     return 0;
    63 }
  • 相关阅读:
    实验三 面向对象分析与设计
    实验二 结构化分析与设计
    软件开发文档与工具的安装与使用
    ATM管理系统
    活动图与流程图
    四则运算
    实验四 决策树算法及应用
    实验三 朴素贝叶斯算法及应用
    实验二 K-近邻算法及应用
    实验一 感知器及其应用
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/12345854.html
Copyright © 2011-2022 走看看