zoukankan      html  css  js  c++  java
  • CF 1616D. Keep the Average High

    传送门

     1 /*
     2 思路:把 a1 + a2 + ... + an >= x * (r - l + 1)  
     3         ===>  a1 + a2 + ... + an - x * (r - l + 1) >= 0
     4     可以等价为对于每个(ai - x) 得到新的ai,则题目变为对于任意区间[l, r], al + ... + ar >= 0.
     5     
     6     我们先考虑: ai分布为  + - + - + - ...  (ai正负交替出现)
     7      
     8     对于 ( a1(-) a2(+) a3(-) ) 这相邻的三个数, 
     9     如果a1 + a2 < 0 和 a2 + a3 < 0只满足其一,则容易想到把满足等式的那个ai(-)不取.
    10     如果两个都满足,则需要用到贪心的思想,我们应该不取中间的a2,因为a2不取,
    11     使得我们可能可以取a1, a3; 如果是不取a1, a3则只有a2可以取.
    12     
    13     如果上述两个等式都不成立,而 a1 + a2 + a3 < 0,则我们贪心的让a3(-)不取,这样对于后面的取与不取有意义
    14     
    15     当然,对于ai(-)如果已经确定是不取的情况得判定
    16     
    17     其他的就是一般的情况   - + - + + + - + + - - -
    18     我们就可以知道,只需要对于ai(+)来判断左右的情况即可.
    19     对于ai(-)则只需判断前面一个元素是不是负数,是不是不取来判断自己是不是不取,因为两个(-)一定是不满足题意的.
    20     
    21     从最小的相邻的局部满足可以得到整体的满足.
    22 */
    23 
    24 
    25 
    26 
    27 #include <bits/stdc++.h>
    28 using namespace std;
    29 
    30 #define ll long long
    31 #define ANS cout<<"ans: ";
    32 
    33 const int N = 1e6 + 10;
    34 
    35 int a[N];
    36 struct node {
    37     int v;
    38     int w;//改数取不取
    39 };
    40 int n;
    41 
    42 inline bool check (int x, int id)
    43 {
    44     if(id == 0) return x - 1 >= 0;
    45     else return x + 1 < n;
    46 }
    47 
    48 void solve ()
    49 {
    50     int T;
    51     cin >> T;
    52     while(T --) {
    53 
    54         cin >> n;
    55         for(int i = 1; i <= n; i ++) cin >> a[i];
    56 
    57         int x;
    58         cin >> x;
    59 
    60         vector<node > vn;
    61         for(int i = 1; i <= n; i ++) vn.push_back({a[i] - x, 1});
    62 
    63         int tot = 0;
    64         for(int i = 0; i < n; i ++) {
    65             if(vn[i].v >= 0) {
    66                 int l, r;
    67                 l = r = 0;
    68                 if(check(i, 0) && vn[i - 1].v < 0 && vn[i - 1].w == 1 && vn[i].v + vn[i - 1].v < 0) l = 1;
    69                 if(check(i, 1) && vn[i + 1].v < 0 && vn[i + 1].w == 1 && vn[i].v + vn[i + 1].v < 0) r = 1;
    70                 if(l + r == 2) tot ++;
    71                 else if(l == 1) tot ++, vn[i - 1].w = 0;
    72                 else if(r == 1) tot ++, vn[i + 1].w = 0;
    73                 else if(l + r == 0) {
    74                     int sum = vn[i].v;
    75                     if(check(i, 0) && vn[i - 1].v < 0 && vn[i - 1].w == 1) sum += vn[i - 1].v;
    76                     if(check(i, 1) && vn[i + 1].v < 0 && vn[i + 1].w == 1) sum += vn[i + 1].v;
    77                     if(sum < 0) tot ++, vn[i + 1].w = 0;
    78                 }
    79             } else if(vn[i].v < 0 && vn[i].w == 1) {
    80                 if(check(i, 0) && vn[i - 1].v < 0 && vn[i - 1].w == 1) tot ++, vn[i].w = 0;
    81             }
    82         }
    83 
    84         ANS;
    85         cout << n - tot << endl;
    86     }
    87 }
    88 
    89 int main()
    90 {
    91     solve();
    92 
    93     return 0;
    94 }
    1
  • 相关阅读:
    sed命令
    awk命令
    let命令
    首先看一下友晶DE-SOC开发板的user manual
    嵌入式FIFO核的调用
    嵌入式ROM核的调用
    用嵌入式块RAM IP核配置一个双口RAM
    如何利用Visio设计一个系统的结构图
    uart通讯协议
    按键消抖试验及一个数码管电子时钟的设计
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/15771749.html
Copyright © 2011-2022 走看看