zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
    不摆烂了,写题
  • 相关阅读:
    使用C#实现计划任务(corn job)
    python 修改xml文件
    redis安装
    Nginx的安装
    nginx配置
    用泛型减少重复代码,使代码更合理、更优雅
    Tomcat server.xml配置详解
    二维码生成
    轻量级的中文分词工具包
    HTML解析利器
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/14440720.html
Copyright © 2011-2022 走看看