传送门
题目描述
n个长度为 m的序列,让你构造一个序列使得这个序列和其他每个序列的相同位置不同数至多为2。
分析
我们用第一个作为模版,如果剩下的n - 1个都和第一个相差小于等于2,直接输出第一个即可
如果最大相差4个,那么就枚举四个不同的位置,选两个,判断合法性
如果最大相差3个,就枚举两个位置,判断合法性
如果大于四个,无解
代码
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
#define _CRT_SECURE_NO_WARNINGS
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const int N = 4e5 + 10;
const ll mod= 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a){
char c=getchar();T x=0,f=1;while(!isdigit(c)){
if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){
x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
int gcd(int a,int b){
return (b>0)?gcd(b,a%b):a;}
vector<int> a[N];
int n,m;
int aaa[N];
int diff(){
int p = 0;
for(int i = 2;i <= n;i++){
int sum = 0;
for(int j = 0;j < m;j++)
sum += (a[i][j] != a[1][j]);
p = max(p,sum);
aaa[i] = sum;
}
return p;
}
int diff(vector<int> p1,vector<int> p2){
int res = 0;
for(int i = 0;i < m;i++) res += (p1[i] != p2[i]);
return res;
}
bool diff(vector<int> &v,int p){
bool flag = 1;
for(int i = 1;i <= n;i++){
int cnt = diff(v,a[i]);
if(cnt <= 2) continue;
if(cnt > 3) return false;
if(v[p] != a[i][p]){
if(flag) v[p] = a[i][p];
else return false;
flag = false;
}
else return false;
}
return 1;
}
bool diff(vector<int> v){
for(int i = 1;i <= n;i++){
int sum = 0;
for(int j = 0;j < m;j++) sum += (a[i][j] != v[j]);
if(sum > 2) return false;
}
return true;
}
int main(){
read(n),read(m);
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++){
int x;
read(x);
a[i].pb(x);
}
int p = diff();
if(p <= 2){
puts("Yes");
for(int i = 0;i < m;i++) printf("%d ",a[1][i]);
return 0;
}
if(p >= 5){
puts("No");
return 0;
}
if(p == 3){
for(int i = 2;i <= n;i++){
if(aaa[i] <= 2) continue;
vector<int> p;
for(int j = 0;j < m;j++) if(a[1][j] != a[i][j]) p.pb(j);
for(int p1 = 0;p1 < 3;p1++)
for(int p2 = 0;p2 < 3;p2++){
if(p1 == p2) continue;
vector<int> back = a[1];
back[p[p1]] = a[i][p[p1]];
if(diff(back,p[p2])){
puts("Yes");
for(int ppppp = 0;ppppp < m;ppppp++) printf("%d ",back[ppppp]);
return 0;
}
}
}
puts("No");
}
if(p == 4){
for(int i = 2;i <= n;i++){
if(aaa[i] <= 3) continue;
vector<int> p;
for(int j = 0;j < m;j++) if(a[1][j] != a[i][j]) p.pb(j);
for(int p1 = 0;p1 < 4;p1++)
for(int p2 = 0;p2 < 4;p2++){
if(p1 == p2) continue;
vector<int> back = a[1];
back[p[p1]] = a[i][p[p1]];
back[p[p2]] = a[i][p[p2]];
if(diff(back)){
puts("Yes");
for(int ppppp = 0;ppppp < m;ppppp++) printf("%d ",back[ppppp]);
return 0;
}
}
}
puts("No");
}
return 0;
}
/**
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████+
* ◥██◤ ◥██◤ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃ + + + +Code is far away from
* ┃ ┃ + bug with the animal protecting
* ┃ ┗━━━┓ 神兽保佑,代码无bug
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*/