zoukankan      html  css  js  c++  java
  • atcoder Keyence Programming Contest 2020 题解

    比赛地址

    A

    题意:给一个(n*m)的初始为白色的矩阵,一次操作可以将一行或一列染成
    黑色,问至少染出(k)个黑点的最少操作次数。
    (n),(m)<=100,(k)<=1e4

    B

    题意:有(n)条线段,用二元组((x,len))表示,占据([x-len,x+len])的位置。
    问最多能选择多少条不相交的线段。
    (n)<=1e5,(x_i),(len_i)<=1e9

    C

    题意:给定(n),(k),(s),构造一个序列(a),使得恰好有(k)个二元组((l,r)),(sum_{i=l}^{r} a[i]) = (s)
    (n)<=1e5,0<=(k)<=(n),(s)<=1e9,(a_i)<=1e9

    D

    题意:有(n)张卡片,初始时每张卡片上面是(a[i]),下面是(b[i])。一次操作可以交换相邻两张牌,
    并将这两张牌翻转。最小化操作次数,使得上面的数组成的序列不降。
    (n)<=18,(a_i),(b_i)<=50

    E

    题意:给定一个(n)(m)边的无向图,每个点可以被染成黑色或白色,每条边可以指定一个[1,1e9]以内的权值。
    找出一种染色和给定边权的方案,使得:
    1.至少存在一个黑点,一个白点;
    2.每个点到与其最近的颜色相异的点的距离为(d_i)
    (n)<=1e5,(m)<=2e5,(d_i)<=1e9

    F

    题意:有一个(n*m)的矩阵,初始时每个点都有一个颜色。
    你可以对其进行任意次操作,每次操作可以任选一行(列),将这一行(列)的点全染成黑(白)色。
    问共能操作出多少种不同的矩阵。答案对998244353取模。
    (n),(m)<=10


    题解

    A

    入门题。根据(n),(m)大小判断染行还是染列。
    时间复杂度:(O(1))

    B

    经典的贪心问题。将所有线段按右端点排序,直接扫一遍,维护一下当前选到的右端点就好。
    时间复杂度:(O(nlogn))

    C

    (傻逼题)。直接指定(k)点权值为(s),剩下的都为(s+1)就行。注意(s)=1e9需要特判。
    时间复杂度:(O(n))

    D

    (n)很小,引导我们可以用指数级别的复杂度做题。首先可以想到暴力枚举所有牌最后哪边朝上。
    考虑如何判定一个方案是否合法,并判断其最小的移动步数。
    我们将这个状态设为(S),它的第(i)位为1就代表它是(b_i)朝上,否则是(a_i)朝上。

    step1

    1的个数一定是个偶数。

    step2

    我们根据这个01序列,可以得到最终的一个无序序列(C)。将这个序列排序,现在要做的就是
    找一个合法的匹配方案。
    可能读者会有些疑惑:这里为什么还要判断是否合法呢?
    考虑那个01序列的另外一层意义:如果某一位为1,那么这一位的这张牌就移动了奇数次,否则就是偶数次。
    这个东西分奇偶讨论一下,用vector存一下所有(c_i)的所有出现位置,一一匹配就行。
    由于(C)中可能有重复元素,最优策略就是原序列中左边的点尽量和排序后的(C)的左边的点匹配。这个是显然的。
    这样,我们就相当于得到了一个排列(P),表示一种匹配方案。

    step3

    那么确定这个方案合法后,如何求出最少的移动步数呢?可以发现这就是这个排列的逆序对个数。把它算出来,更新答案。
    时间复杂度:O((2^n) ( imes) (n^2))

    E

    考虑从何下手这个问题。
    首先,我们肯定希望这个最短路尽量好求一些。最好是所有的匹配都是两点直接相连的。
    当然事实确实是这样的。这里给出一个证明。
    考虑反证法:如果存在一种匹配方案(a->c),(b->c),(a),(b)是黑点,(c)是白点,且这三点的连边情况是:(a---b---c)
    首先,如果(b)(c)匹配,那么(a)不会和其他点匹配。

    情况1

    (d_a)<(d_b):显然这种方案是不合法的;

    情况2

    (d_a)>=(d_b):显然可以将(b)换成白点,(c)换成黑点((c)不换也行,具体看情况)。
    因此,若有解,一定存在一种匹配方案,使得所有点都和它直接相连的一个点匹配。
    接下来,考虑这样的一个匹配过程:
    一个节点(A)找到了另一个节点(B),与其匹配。那么那个节点(B)有两种选择:一是和(A)匹配,一是和其他节点匹配。
    重点是,无论如何匹配,(d_B)一定大于等于(d_A)
    由此下去,一定有一个最终状态,节点(B)别无他选,只能和(A)匹配。我们发现了隐藏在题目中的单调性。
    由此,我们得到了一个做法:先将所有节点按(d_i)从小到大排序,然后对于每个节点,
    先找有没有与其直接相连的未被染色的点,且两者的(d)相同。若有,则两点互相匹配,若没有,再找一个已被染色的点,
    与其匹配即可。若还没有,则无解。
    注意一定要先找能互相匹配的点,因为一次可以染两个节点的色。
    时间复杂度:(O(nlogn+m))

    F

    待填坑~


    代码

    先咕在这里,等写完F再放吧~

  • 相关阅读:
    查找符号链接的目标
    升级到VS2013.Update.4的问题
    (转载)FT232RL通信中断问题解决办法总结
    WinForms中的Label的AutoSize属性
    VS2010中的查找和替换中正则的使用
    为什么SqlTransaction.Rollback会抛出SqlException(11,-2)(即SQL超时异常)
    腾讯内推 社会招聘 自助操作内推
    腾讯内推流程 社会招聘 腾讯面试流程
    golang sort包的使用(一)
    golang 结构体中空数组被序列化成null解决方法
  • 原文地址:https://www.cnblogs.com/Purple-wzy/p/12210564.html
Copyright © 2011-2022 走看看