E. Almost FaultTolerant Database 题解(思维+枚举)

题目链接

题目大意

给你一个\(n \times m(n\times m\leq 250000)\)的矩阵

你要构造一个长度为\(m(1\leq a[i] \leq 1e9)\)的数组,使得矩阵每一行的元素最多2个和他不同

题目思路

其实看到这个很容易想到枚举,因为只有至多两个元素不同

但是如何枚举却是一个问题

1:其他行的元素与第一行的元素不同的值最多为2那么显然可以直接输出第一行元素

2:其他行的元素与第一行的元素不同的值最多大于4那么显然直接输出No

3: 关键是如果最大值是3/4该怎么办,显然假设现在答案为第一行元素,那么答案必定要改变一个值为另一个序列的值,还有可能还要改变一个值,但是暂时不知道要改什么,先设为-1。用新序列去与所有序列比较,当不同数大于3的时候,那就不合理。当不同数为3的时候,如果这个时候存在-1,那么将-1改成和当前序列这个位置相同的数,否则就不合理。

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5e4+5;
vector<int> vec[maxn];
int n,m;
int cal(vector<int> a,vector<int> b){ //计算机两个数组的不同值
    int cnt=0;
    for(int i=1;i<=m;i++){
        cnt+=(a[i]!=b[i]);
    }
    return cnt;
}
void pr(vector<int> a){
    for(int i=1;i<=m;i++){
        if(a[i]==-1) a[i]=1;
        printf("%d%c",a[i],i==m?'\n':' ');
    }
}
void check(vector<int> temp){
    for(int i=1;i<=n;i++){
        if(cal(temp,vec[i])>3){
            return ;
        }else if(cal(temp,vec[i])==3){
            for(int j=1;j<=m;j++){
                if(temp[j]==-1){
                    temp[j]=vec[i][j];
                    break;
                }
                if(j==m){
                    return ;
                }
            }
        }
    }
    printf("Yes\n");
    pr(temp);
    exit(0);
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        vec[i].push_back(-1);
        for(int j=1,x;j<=m;j++){
            scanf("%d",&x);
            vec[i].push_back(x);
        }
    }
    int ma=0,ma_id;
    for(int i=2;i<=n;i++){
        if(ma<cal(vec[1],vec[i])){
            ma=cal(vec[1],vec[i]);
            ma_id=i;
        }
    }
    if(ma<=2){
        printf("Yes\n");
        pr(vec[1]);
    }else if(ma>4){
        printf("No\n");
    }else if(3<=ma&&ma<=4){
        vector<int> pos;
        for(int j=1;j<=m;j++){ //把不同的位置放在pos里面
            if(vec[1][j]!=vec[ma_id][j]){
                pos.push_back(j);
            }
        }
        for(int j=0;j<pos.size();j++){
            for(int k=0;k<pos.size();k++){
                if(j==k) continue;
                vector<int> temp=vec[1];
                temp[pos[j]]=vec[ma_id][pos[j]];
                temp[pos[k]]=-1;
                check(temp);
            }
        }
        printf("No\n");
    }
    return 0;
}

不摆烂了,写题
原文地址:https://www.cnblogs.com/hunxuewangzi/p/14440720.html