菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
378
0

E. Almost Fault-Tolerant Database 暴力枚举 + 分类讨论 + 思维 Codeforces Round #704 (Div. 2)

原创
05/13 14:22
阅读数 75436

E. Almost Fault-Tolerant Database 暴力枚举 + 分类讨论 + 思维

题目大意:

给你 \(n\) 个单元,每一个单元是一个长度为 \(m\) 的序列,让你构造一个单元 \(ans\) ,满足 \(ans\) 这个单元和给定的 \(n\) 个单元的每一个单元最多有两个位置的数不一样,如果存在这个单元,输出 "Yes" 并输出这个单元,如果没有则输出 "No"

题解:

首先假设答案就是 第一个单元,然后和其他以一比对,进行分类讨论:

  • 如果和其他最多不同 \(dif<=2\) 那么直接输出答案
  • 如果 \(dif>4\) ,那么不可能构造出来
  • 如果 \(dif==3||dif==4\) 则要暴力枚举,首先找到那个 \(dif\) 最大的位置,(假设我枚举改动 \(dif\) 最大的这个位置),其中至少有一个位置是要变成第一个单元的,然后如果 \(dif==4\) ,那么另一个位置也要和第一个单元相同,如果 \(dif==3\) ,那么就在后面比较的过程中寻找另一个要变化的位置,但是容易发现可以把 \(dif==3\)\(dif==4\) 归在一类

这个题目其实发现任意两个单元最多只有4个是不一样的这个是很简单的,但是发现这个之后想到直接暴力枚举,如果 \(dif==4\) ,那么毫无疑问,直接暴力枚举两个相同即可。

但是 \(dif==3\) ,那么除了要有一个和第一个单元相同,还会有一个是不固定的答案,也就是一个变量,需要在后面比较的时候获得,这个需要注意!

#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5+10;
vector<vector<int>>a;
int n,m;
vector<int> Diff(int x,int y){
    vector<int>ans;
    for(int i=0;i<m;i++){
        if(a[x][i]!=a[y][i]) ans.push_back(i);
    }
    return ans;
}
bool check(vector<int>&tmp){
    for(int i=0;i<n;i++){
        int cnt = 0,pos = -1;
        for(int j=0;j<m;j++){
            if(a[i][j]!=tmp[j]) cnt++;
            if(tmp[j]==-1) pos = j;
        }
        if(cnt>3) return false;
        if(cnt==3){
            if(pos!=-1) tmp[pos] = a[i][pos];
            else return false;
        }
    }
    return true;
}
void Print(vector<int>tmp){
    printf("Yes\n");
    for(int i=0;i<tmp.size();i++) {
        if(tmp[i]==-1) printf("1 ");
        else printf("%d ",tmp[i]);
    }
    printf("\n");
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        vector<int>v;
        for(int j=0,x;j<m;j++){
            scanf("%d",&x);
            v.push_back(x);
        }
        a.push_back(v);
    }
    int mx_id = 0,dif = 0;
    for(int i=1;i<n;i++){
        int res = Diff(0,i).size();
        if(res>dif) dif = res,mx_id = i;
    }
    if(dif<=2) Print(a[0]);
    else if(dif>4) printf("No\n");
    else{
        vector<int> now = Diff(0,mx_id);
        for(int i=0;i<now.size();i++){
            for(int j=i+1;j<now.size();j++){
                vector<int>tmp = a[mx_id];
                int x = now[i],y = now[j];
                tmp[x] = -1,tmp[y] = a[0][y];
                if(check(tmp)){
                    Print(tmp);
                    return 0;
                }
                tmp[x] = a[0][x],tmp[y] = -1;
                if(check(tmp)){
                    Print(tmp);
                    return 0;
                }
            }
        }
        printf("No\n");
    }
}

发表评论

0/200
378 点赞
0 评论
收藏