分类讨论
k
1
k1
k1和
k
2
k2
k2的情况。
把相同的字符串染成相同的颜色。
然后还要记一下每个串的反串(每一位取反)。
p
o
s
pos
pos记录每种颜色的一个位置。
枚举一下答案是什么再判一下是否可行。
写的时候要想清楚下标是颜色还是字符串标号。
注意
k
1
=
0
,
k
2
=
0
k1=0,k2=0
k1=0,k2=0的情况是
u
n
s
i
g
n
e
d
l
o
n
g
l
o
n
g
unsigned\ long\ long
unsigned long long。因为
m
⩽
50
m \leqslant 50
m⩽50。
而且这种情况上界是
2
m
2^m
2m。
#include<bits/stdc++.h>
#define ull unsigned long long
#define re register
#define cs const
using namespace std;
cs int N=55;
char s[N][N],rev[N][N],ans[N];
int n,m,k1,k2,flag=0;
int cnt[N],same[N][N];
int col[N],rcol[N],pos[N],tot=0;
inline bool cmp(char *a,char *b){
for(int re i=1;i<=m;++i)
if(a[i]!=b[i]) return false;
return true;
}
inline void update(char *a,char *b){
bool f=0;
for(int re i=1;i<=m;++i){
if(a[i]=='Y'&&b[i]=='N'){f=true;break;}
if(a[i]=='N'&&b[i]=='Y') return;
}if(f) for(int re i=1;i<=m;++i) a[i]=b[i];
}
int main(){
// freopen("bestjob.in","r",stdin);
// freopen("bestjob.out","w",stdout);
scanf("%d%d%d%d",&n,&m,&k1,&k2);
for(int re i=1;i<=m;++i) ans[i]='Y';
for(int re i=1;i<=n;++i){
scanf("%s",s[i]+1);
for(int re j=1;j<=m;++j)
if(s[i][j]=='Y') rev[i][j]='N';
else rev[i][j]='Y';
}
for(int re i=1;i<=n;++i)
for(int re j=i+1;j<=n;++j)
if(cmp(s[i],s[j])) same[i][j]=same[j][i]=1;
for(int re i=1;i<=n;++i){
if(!col[i]) col[i]=++tot,pos[tot]=i;
for(int re j=i+1;j<=n;++j)
if(same[i][j]) col[j]=col[i];
}for(int re i=1;i<=n;++i) ++cnt[col[i]];
for(int re i=1;i<=n;++i)
for(int re j=1;j<=tot;++j)
if(cmp(rev[i],s[pos[j]])) rcol[i]=j;
if(k1&&k2){
for(int re i=1;i<=tot;++i)
for(int re j=1;j<=tot;++j) if(i!=j)
if(cnt[i]==k1&&cnt[j]==k2&&rcol[pos[i]]==j)
flag=1,update(ans,s[pos[i]]);
if(flag) for(int re i=1;i<=m;++i) putchar(ans[i]);
else puts("-1");
return 0;
}
if(k1&&(!k2)){
for(int re i=1;i<=n;++i)
if(cnt[col[i]]==k1&&!rcol[i])
flag=1,update(ans,s[i]);
if(flag) for(int re i=1;i<=m;++i) putchar(ans[i]);
else puts("-1");
return 0;
}
if((!k1)&&k2){
for(int re i=1;i<=n;++i)
if(cnt[col[i]]==k2&&!rcol[i])
flag=1,update(ans,rev[i]);
if(flag) for(int re i=1;i<=m;++i) putchar(ans[i]);
else puts("-1");
return 0;
}
for(int re i=1;i<=m;++i) ans[i]='N';
for(ull re state=0;state<(1ull<<m);++state){
int haha=1;
for(int re j=1;j<=m;++j)
if(state&(1ull<<(j-1))) ans[m-j+1]='Y';
else ans[m-j+1]='N';
for(int re i=1;i<=n;++i)
if(cmp(ans,s[i])||cmp(ans,rev[i]))
{haha=0;break;}
if(haha){
for(int re i=1;i<=m;++i)
putchar(ans[i]);
return 0;
}
}puts("-1");
}