题意:
给出k个长n的字符串,k*n<=5000,问是否存在一个字符串,使得每个字符串恰好交换两个不同位置的字母都能得到。
思路:
先比较给出的第一个字符串和其他字符串,如果都是有2、3、4个不同或者0个不同但是有一个字符出现两次以上的,有解,其他无解。
判断完之后取最多不同的,记录下第一个字符串中不同的位置,然后枚举这几个位置和其他的字符交换,再判断是否是最终字符串。注意每个字符串一定要交换字符。
代码:
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <map>
#include <list>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <sstream>
#define pb push_back
#define X first
#define Y second
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define pii pair<int,int>
#define qclear(a) while(!a.empty())a.pop();
#define lowbit(x) (x&-x)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define mst(a,b) memset(a,b,sizeof(a))
#define cout3(x,y,z) cout<<x<<" "<<y<<" "<<z<<endl
#define cout2(x,y) cout<<x<<" "<<y<<endl
#define cout1(x) cout<<x<<endl
#define IOS std::ios::sync_with_stdio(false)
#define SRAND srand((unsigned int)(time(0)))
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
using namespace std;
const double PI=acos(-1.0);
const int INF=0x3f3f3f3f;
const ll INFF=0x3f3f3f3f3f3f3f3f;
const ll mod=1000000007;
const double eps=1e-5;
const int maxn=2005;
const int maxm=20005;
const int base=27;
int n,m;
char str[2505][5005];
int hanming[5005];
int cnt[30];
int cnt0[30];
char ans[5005];
bool isdup=0;
bool check(int now) {
for(int i=0; i<n; i++) {
if(i==now)continue;
int nowcnt=0;
for(int j=0; j<m; j++) {
if(str[now][j]!=str[i][j]) {
nowcnt++;
}
}
if(nowcnt!=2&&nowcnt!=0)
return 0;
if(nowcnt==0&&isdup==0)
return 0;
}
for(int i=0; i<m; i++)
ans[i]=str[now][i];
ans[m]='\0';
return 1;
}
void solve() {
sdd(n,m);
for(int i=0; i<n; i++) {
scanf("%s",str[i]);
}
int mark1=-1,mark2=-1;
mst(hanming,0);
for(int i=1; i<n; i++) {
for(int j=0; j<m; j++) {
if(str[0][j]!=str[i][j]) {
hanming[i]++;
}
}
}
bool ok=1;
mst(cnt0,0);
for(int i=0; i<m; i++) {
cnt0[str[0][i]-'a']++;
if(cnt0[str[0][i]-'a']>1)
isdup=1;
}
for(int i=1; i<n; i++) {
mst(cnt,0);
for(int j=0; j<m; j++) {
cnt[str[i][j]-'a']++;
}
for(int j=0; j<26; j++) {
if(cnt[j]!=cnt0[j]) {
ok=0;
}
}
}
int mark=-1;
int marklen=0;
if(ok) {
for(int i=1; i<n; i++) {
if(hanming[i]>4||hanming[i]==1) {
ok=0;
}
if(hanming[i]>marklen)mark=i;
}
}
if(mark==-1)ok=0;
if(ok) {
vector<int>v;
v.clear();
for(int i=0; i<m; i++) {
if(str[0][i]!=str[mark][i]) {
v.pb(i);
}
}
bool flag=0;
for(int i=0; i<v.size(); i++) {
int now=v[i];
for(int j=0; j<m; j++) {
if(j==now)
continue;
swap(str[0][now],str[0][j]);
if(check(0)) {
flag=1;
break;
}
swap(str[0][now],str[0][j]);
swap(str[mark][now],str[mark][j]);
if(check(mark)) {
flag=1;
break;
}
swap(str[mark][now],str[mark][j]);
}
if(flag)
break;
}
ok=flag;
}
bool flag=0;
for(int i=0; i<n; i++) {
if(hanming[i]!=0) {
flag=1;
}
}
if(flag==0||n==1) {
for(int i=0; i<m; i++)
ans[i]=str[0][i];
ans[m]='\0';
swap(ans[0],ans[1]);
ok=1;
}
if(ok)
printf("%s\n",ans);
else
printf("-1\n");
return ;
}
int main() {
#ifdef LOCAL
freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
#else
// freopen("","r",stdin);
// freopen("","w",stdout);
#endif
solve();
return 0;
}