E. Almost Fault-Tolerant Database
题意:
- 给你n份长度为m的数组的拷贝。(这n份是事先存储在计算机中的)
- 可是发生了error,
对于每一份
导致有些位置的元素变化了。最多有两个位置变化。
问:
是否可以还原出原数组。
思路:
- 以第一份 a 【 1 】 a【1】 a【1】为基准,去考虑其他的。
- 对于 i ∈ [ 2 , n ] i\in[2,n] i∈[2,n] 的 a 【 i 】 a【i】 a【i】 与 a 【 1 】 a【1】 a【1】进行比较
- case1:上面的比较中当所有拷贝( i ∈ [ 2 , n ] i\in[2,n] i∈[2,n] 的 a 【 i 】 a【i】 a【i】)都与 a 【 1 】 a【1】 a【1】相差最多两个,那么直接输出第一个即可。
- case2:上面的比较中当所有拷贝( i ∈ [ 2 , n ] i\in[2,n] i∈[2,n] 的 a 【 i 】 a【i】 a【i】)都与 a 【 1 】 a【1】 a【1】相差超过4个,那么不论如何都构造不出答案
- case3:分别讨论
d
i
f
=
3
dif=3
dif=3和
d
i
f
=
4
dif=4
dif=4的情况(具体看实现)
对于这个case的解决主要思路是枚举。
AC(Alan–yyds)
/*
皮卡丘冲鸭!
へ /|
/\7 ∠_/
/ │ / /
│ Z _,< / /`ヽ
│ ヽ / 〉
Y ` / /
イ● 、 ● ⊂⊃〈 /
() へ | \〈
>ー 、_ ィ │ //
/ へ / ノ<| \\
ヽ_ノ (_/ │//
7 |/
>―r ̄ ̄`ー―_
*/
#include <iostream>
#include <bits/stdc++.h>
#define For(i,x,y) for(int i=(x); i<=(y); i++)
#define fori(i,x,y) for(int i=(x); i<(y); i++)
#define rep(i,y,x) for(int i=(y); i>=(x); i--)
#define mst(x,a) memset(x,a,sizeof(x))
#define pb push_back
#define sz(a) (int)a.size()
#define ALL(x) x.begin(),x.end()
#define mp make_pair
#define fi first
#define se second
#define db double
#define debug(a) cout << #a << ": " << a << endl
using namespace std;
typedef long long LL;
typedef long long ll;
typedef unsigned long long ULL;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
typedef pair<int,int>pa;
typedef pair<ll,ll>pai;
typedef pair<db,db> pdd;
const int N = 2e5+10;
const int M = 1e5;
const int maxn=2e5+5e4+10;
const db eps = 1e-8;
const db pi = acos(-1.0);
template<class T> bool uin(T &a, T b) { return a > b ? (a = b, true) : false; }
template<class T> bool uax(T &a, T b) { return a < b ? (a = b, true) : false; }
vector<int>a[maxn];
int n, m;
//
int check(vector<int> a, vector<int> b){
int cnt = 0;
fori(i,0,m)cnt += a[i]!=b[i];
return cnt;
}
//cnt==3
bool check(vector<int>& tmp, int pos){
tmp[pos] = 0;//tmp[pos] = a[0][pos];
fori(i,0,n){
int cnt = check(tmp,a[i]);
if(cnt<=2)continue;
else if(cnt>3)return 0;
else {
if(tmp[pos]!=a[i][pos]){
if(!tmp[pos])tmp[pos] = a[i][pos];
else return 0;
}else return 0;
}
}
if(!tmp[pos])tmp[pos] = 1;
return 1;
}
//cnt4 check all
bool check(vector<int>tmp){
int cnt = 0;
fori(i,1,n){
cnt = check(tmp,a[i]);
if(cnt>2)return 0;
}
return 1;
}
//output
void out(vector<int> tmp){
puts("Yes");
for(int j = 0; j < m; j ++ ){
if(j!=0)printf(" ");
printf("%d", tmp[j]);//cout<<x<<' ';
}
puts("");
exit(0);
}
int main()
{
// ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
scanf("%d%d", &n, &m);//cin>>n>>m;
fori(i,0,n)fori(j,0,m){
int x; scanf("%d", &x);//cin>>x;
a[i].pb(x);
}
int dif = 0;
fori(i,1,n)dif=max(dif,check(a[0],a[i]) );
if(dif<=2)out(a[0]);
else if(dif>4)return printf("No")*0;
else {
int cnt = 0;
fori(i,1,n){
//bool ok = true;
cnt = check(a[0],a[i]);
if(cnt<=2)continue;
else if(cnt==3){
//vector<int>tmp = a[0];
/// debug(i);
vector<int>pos;
fori(j,0,m)if(a[0][j] != a[i][j])pos.pb(j);
for(int rot1 = 0; rot1 < 3; rot1 ++ ){
for(int rot2 = 0; rot2 < 3; rot2++){
if(rot1==rot2)continue;
vector<int> tmp = a[0];
tmp[pos[rot1]] = a[i][pos[rot1]];
if(check(tmp,pos[rot2])) out(tmp);/// find answer
}
}
return printf("No")*0;
/// if(ok)out(tmp);
}else {//cnt == 4
vector<int>pos;
fori(j,0,m)if(a[0][j] != a[i][j])pos.pb(j);
for(int rot1 = 0; rot1 < 4; rot1 ++ ){
for(int rot2 = rot1+1; rot2 < 4; rot2++){
vector<int>tmp = a[0];
tmp[pos[rot1]] = a[i][pos[rot1]];
tmp[pos[rot2]] = a[i][pos[rot2]];
if(check(tmp)) out(tmp);
}
}
/// if(ok) out(tmp);
return printf("No")*0;
}
}
}
return 0;
}