E. Almost Fault-Tolerant Database
这题给你
n
∗
m
n*m
n∗m 个数,问你能否找到一行
m
m
m 个数,使得这
m
m
m 个数与每一行不同的数不超过
2
2
2 个
我们先考虑答案肯定和第一行不超过两个数(如果存在) 那么我们去拿第一行假设作为答案与其余行求
m
a
x
d
i
f
f
maxdiff
maxdiff 如果
m
a
x
d
i
f
f
maxdiff
maxdiff >=
5
5
5 肯定无解,因为你只能换两个位置
5
−
2
=
3
>
=
2
5-2=3 >= 2
5−2=3>=2 那么当
m
a
x
d
i
f
f
<
=
2
maxdiff <= 2
maxdiff<=2 肯定输出第一行本身 如果
m
a
x
d
i
f
f
=
4
maxdiff = 4
maxdiff=4 则交换其中两个元素,
m
a
x
d
i
f
f
=
3
maxdiff=3
maxdiff=3 比较麻烦,先交换一个,然后看是否满足情况 如果继续
m
a
x
d
i
f
f
=
3
maxdiff = 3
maxdiff=3 则做组合交换
3
∗
3
3*3
3∗3 情况,题解说
3
3
3 种情况 可能还是有不同的地方 另外代码也写的不够美观 感觉定义的太随意了 代码就越来越臃肿
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<stack>
#include<cstring>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
using namespace std;
#define ll long long
const int MAX_N = 250025;
vector<int> vt[MAX_N];
int ans[MAX_N],cnt[MAX_N],maxx,xb,n,m,tmp[5],tmpLen,maxx_,xb_,tmp_[5],tmpLen_,maxx__,xb__;
void findDiff()
{
maxx = -1;
for(int i = 1;i<=n;++i) cnt[i] = 0;
for(int i = 1;i<=n;++i)
{
for(int j = 1;j<=m;++j)
{
if(vt[i][j]!=ans[j]) cnt[i]++;
}
if(cnt[i]>maxx)
{
maxx = cnt[i];
xb = i;
}
}
}
void findDiffOne()
{
maxx_ = -1;
for(int i = 1;i<=n;++i) cnt[i] = 0;
for(int i = 1;i<=n;++i)
{
for(int j = 1;j<=m;++j)
{
if(vt[i][j]!=ans[j]) cnt[i]++;
}
if(cnt[i]>maxx_)
{
maxx_ = cnt[i];
xb_ = i;
}
}
}
void findDiffTwo()
{
maxx__ = -1;
for(int i = 1;i<=n;++i) cnt[i] = 0;
for(int i = 1;i<=n;++i)
{
for(int j = 1;j<=m;++j)
{
if(vt[i][j]!=ans[j]) cnt[i]++;
}
if(cnt[i]>maxx__)
{
maxx__ = cnt[i];
xb__ = i;
}
}
}
void GOOD()
{
printf("Yes\n");
for(int i = 1;i<=m;++i)
{
i==m?printf("%d\n",ans[i]):printf("%d ",ans[i]);
}
}
bool gao(int x,int y,int initXb)
{
for(int i = 1;i<=m;++i) ans[i] = vt[1][i];
ans[tmp[x]] = vt[initXb][tmp[x]];
ans[tmp[y]] = vt[initXb][tmp[y]];
findDiff();
if(maxx<=2)
{
return true;
}
return false;
}
bool gaoOne(int x)
{
ans[tmp_[x]] = vt[xb_][tmp_[x]];
findDiffTwo();
if(maxx__<=2)
{
return true;
}
return false;
}
int main()
{
int x;
scanf("%d%d",&n,&m);
for(int i = 1;i<=n;++i) vt[i].push_back(-1);
for(int i = 1;i<=n;++i)
{
for(int j = 1;j<=m;++j)
{
scanf("%d",&x);
vt[i].push_back(x);
}
}
for(int i = 1;i<=m;++i) ans[i] = vt[1][i];
findDiff();
if(maxx<=2)
{
GOOD();
}
else if(maxx>=5)
{
printf("No\n");
}
else if(maxx==3)
{
tmpLen = 0;
for(int i = 1;i<=m;++i)
{
if(ans[i]!=vt[xb][i]) tmp[++tmpLen] = i;
}
for(int i = 1;i<=tmpLen;++i)
{
for(int j = 1;j<=m;++j) ans[j] = vt[1][j];
ans[tmp[i]] = vt[xb][tmp[i]];
findDiffOne();
if(maxx_<=2)
{
GOOD();
return 0;
}
if(maxx_>3)
{
continue;
}
tmpLen_ = 0;
for(int j = 1;j<=m;++j) if(ans[j]!=vt[xb_][j]) tmp_[++tmpLen_] = j;
for(int j = 1;j<=tmpLen_;++j)
{
int lastOne = ans[tmp_[j]];
if(gaoOne(j))
{
GOOD();
return 0;
}
else
{
ans[tmp_[j]] = lastOne;
}
}
}
printf("No\n");
}
else
{
tmpLen = 0;
for(int i = 1;i<=m;++i)
{
if(ans[i]!=vt[xb][i]) tmp[++tmpLen] = i;
}
int initXb = xb;
if(gao(1,2,initXb)||gao(1,3,initXb)||gao(1,4,initXb)||gao(2,3,initXb)||gao(2,4,initXb)||gao(3,4,initXb))
{
GOOD();
}
else
{
printf("No\n");
}
}
return 0;
}