Codeforces Round #704 (Div. 2) E
题解:
把第一个数组当成初始序列,查看其它序列,进行修改,最终求出答案
先分析直接有答案的:
如果初始序列和其他序列进行对比不同项 不超过2个,初始序列即为答案。
如果初始序列和其他序列进行对比不同项 超过4个,不可能有答案。
然后分析如何进行修改,对于 除了初始序列剩下的序列 与 初始序列进行对比:
不同项有四个,那么必然得修改其中的任意两个,共6中情况,修改后查看其他序列是否符合要求。
不同项最大为三个,任意选出不同项为三个的序列进行修改即可,原因是如果该序列修改完不能满足要求的话,不可能有答案。
不同项为三个,可以只修改一个点,也可以修改两个点,这得分类讨论。如果修改一个点的话,允许其他序列修改一个值。
#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define pb push_back
const int N = 250020;
int n, m;
vector <int> v[N];
void print(){
cout << "Yes" << endl;
for(int i = 0;i < m;i ++)
cout << v[0][i] << " ";
cout << endl;
}
int check(){
for(int i = 1;i < n;i ++) {
int num = 0;
for(int j = 0;j < m;j ++) {
if(v[0][j] != v[i][j])
num ++;
}
if(num >= 3) return 0;
}
print();
return 1;
}
bool change(int y){
int st = 0,save;
for(int i = 1;i < n;i ++){
int k = 0;
for(int j = 0;j < m;j ++){
if(!st && j == y) continue;
if(v[i][j] != v[0][j]) k ++;
}
if(k >= 3){
if(st) v[0][y] = save;
return 0;
}
if(k==2&&!st){
save = v[0][y];
v[0][y] = v[i][y];
st = 1;
}
}
print();
return 1;
}
int main(){
int x;
scanf("%d%d", &n, &m);
for(int i = 0;i < n;i ++) {
for(int j = 0;j < m;j ++) {
scanf("%d",&x);
v[i].pb(x);
}
}
int t, st = 0, yes = 1;
for(int i = 1;i < n;i ++) {
int num = 0;
for(int j = 0;j < m;j ++) {
if(v[0][j] != v[i][j])
num ++;
}
if(num > 4) {
cout << "No" << endl;
return 0;
}
if(num == 3 && st == 0) {
t = i;
yes = 0;
}
if(num == 4) {
t = i;
st = 1;
yes = 0;
}
}
if(yes == 1){
print();
return 0;
}
vector <int> z;
for(int i = 0;i < m;i ++)
if(v[0][i] != v[t][i])
z.pb(i);
if(st == 0){ // 3
for(int i = 0;i < z.size();i ++) {
int save1 = v[0][z[i]];
v[0][z[i]] = v[t][z[i]];
if(check()) return 0;
for(int j = 0;j < z.size();j ++) {
if(i == j) continue;
if(change(z[j])) return 0; //!
}
v[0][z[i]] = save1;
}
}
else{ // 4
for(int i = 0;i < z.size();i ++) {
int save1 = v[0][z[i]];
v[0][z[i]] = v[t][z[i]];
for(int j = i + 1;j < z.size();j ++) {
int save2 = v[0][z[j]];
v[0][z[j]] = v[t][z[j]];
if(check()) return 0;
v[0][z[j]] = save2;
}
v[0][z[i]] = save1;
}
}
cout << "No" << endl;
return 0;
}
/*
9 9
1 2 2 2 2 1 2 2 2
1 2 2 1 1 2 2 2 1
1 2 2 1 2 2 2 2 1
1 2 2 1 2 2 1 2 1
1 2 2 1 2 2 1 2 1
1 2 2 1 2 2 2 2 1
1 2 2 2 1 1 2 2 1
1 2 2 2 1 1 2 2 1
1 2 1 2 2 2 2 2 1
Yes
1 2 2 2 2 2 2 2 1
5 5
1 2 3 4 5
6 11 3 4 7
1 8 3 12 16
1 13 3 4 17
1 8 14 4 15
Yes
1 8 3 4 7
*/