CF1492E Almost Fault-Tolerant Database

给出n个长度为m的数组,求出一个数组,与这些数组各自的不同点最多两个,无解输出NO。

这问题很简洁。

首先看无解的情况,如果设数组集合为S,如果S中数组A和B 有>=5个不同点,显然无解。

因为答案数组与数组A最多两个不同点,这两个不同点最多可以抵消5个不同点中的两个,剩下的三个必然与A一样,从而与B不一样。

因此,假设现在的S中两两数组最多4个不同点。

现在可以考虑三个数组A,B,C的情况,感觉有MO组合题的味道。

假设A和B只有前4个元素不同,那么C与A在前四个元素中,必然至少有2个元素相同,C与B也一样。 嗯?是吗?

 

首先,答案数组与第一个数组A最多相差两个数字,因此,我们只要枚举A中的不同点的位置修改得到答案数组。

其次,如果别的数组与数组A不同点个数<=2,那么只要把数组A当作答案数组即可。

刚才又说过了,如果有一个数组与数组A不同点个数>=5,那么无解。

因此,只需要考虑其余数组与数组A的不同点个数都是3或者4的情况。

然后呢,光是以A为中心,其余数组与A比较是不够的,其余数组之间两两的关系也很重要。

那么我们再加一个数组B来讨论,假设数组B与A只差3个。

假设是前3个。

然后为了简化问题,我们大胆下一个简化性的结论:其余数组除了前3位,后面最多有一位与数组A不同。

想了一下,这条结论是错的。

但是如果除了A,B以外,还存在一个数组C使得前三位与A的都不同,那么C的除了前3位的后缀都是与A相同的。

这好像也不对。

应该是如果存在一个数组C使得前三位与A的都不同,那么C的除了前3位的后缀都是与A最多一个地方不同。(这不就是任两个数组不超过4个不同的推论吗)

这样的话,我们似乎可以按照前三位的二进制(是否与A相同)来分类数组。

 然后最好从简单的开始讨论,比如全部都是000(前三位都与A不同)

那么答案数组至少要修改A的前三位中的一位,如果修改了一位后的答案数组,与其余数组比较,依然有000,那么说明答案数组两个地方都要修改在A的前三位上。

枚举check即可。

 

感觉这样讨论下去是死路啊,首先我们不知道修改成什么数值。

卧槽,看了题解,好像让A和B比较确定出不同点,最多4个,然后直接枚举这四个点哪些需要修改(但我们先不管修改成什么)

然后check过去就是了。

 

posted @ 2021-03-13 11:41  AngelKnows  阅读(51)  评论(0)    收藏  举报