zoukankan      html  css  js  c++  java
  • CF1468H 【K and Medians】

    由题意可得通过每次操作可以消去$k-1$个数,因此对于$(n-m)\%(k-1) e 0$的情况必然是无解的,直接输出$NO$即可

    考虑消去实现的充要条件:

    显然消去的最后一步必然是以$b$序列中的某一元素为中位数进行的,即有解的充要条件为可以构造出以下情况:$exists iin [1,m] , S.t. b_i$两侧各有$(k-1)/2$个不在$b$序列中的数

    考虑有解状态的构造可能性:

    若$i$为上述最后一次消去的中位数,则显然要求初始状态下小于$b_i$的应被消去的数个数大于等于$(k-1)/2$,同理大于$b_i$的也需满足同样条件

    满足以上条件则必能通过对原序列进行的若干次消去达到有解状态,下面提供一种消去方案

    设初始状态下小于$b_i$的应被消去的数有$x$个,大于$b_i$的应被消去的数有$y$个

    若$x-(k-1)/2>=k-1$则对左侧进行若干次消去$k-1$个数的操作直到不等式不再成立,设此时小于$b_i$的应被消去的数有$x_0$个,$y$同理

    由$x+y$为$k-1$的倍数可得$x_0+y_0$也为$k-1$的倍数,若$x=(k-1)/2$且$y=(k-1)/2$则已达到上述情况,否则左侧消去$x_0-(k-1)/2$个数,右侧消去$y_0-(k-1)/2$个数即可

    答案的处理

    对于每个数,只需通过上述充要条件$O(1)$判断是否能达到有解状态即可,总复杂度$O(n)$


    代码

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    const int maxn=2e5+10;
    int t,n,k,m,b[maxn];
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d%d",&n,&k,&m);
            for(int i=1;i<=m;i++)
                scanf("%d",&b[i]);
            if((n-m)%(k-1))
            {
                printf("NO
    ");
                continue;
            }
            bool f=0;
            for(int i=1;i<=m;i++)
                if(b[i]-i>=(k-1)/2&&n-m+i-b[i]>=(k-1)/2)
                {
                    printf("YES
    "),f=1;
                    break;
                }
            if(!f)
                printf("NO
    ");
        }
        return 0;
    }
  • 相关阅读:
    android 基础项目及开发出现:error opening trace file: No such file or directory错误解决
    Android开发遇到的问题
    Don‘t talk.Just do it.
    LeetCode——Word Break
    晋IT分享成长沙龙集锦
    logback 简单配置总述
    HDU 2119 Matrix 简单二分匹配
    华为招聘机试整理5:简单四则运算
    JSP简单练习-猜字母游戏
    Codechef July Challenge 2014部分题解
  • 原文地址:https://www.cnblogs.com/ivanovcraft/p/14394521.html
Copyright © 2011-2022 走看看