*题解:CF903E Swapping Characters
解析
手玩构造,发现玩不出来,于是考虑处理出一些解然后判定是否合法。根据题意,如果有解的话,所有串都是由这个解交换两个字符得来的。因此对于任意一个串,解必定出现在所有交换两个字符后的串中,可以只考虑一个串 \(t\),可能解的数量为 \(O(n^2)\) 个。
接下来判定是否合法,即判断一个候选解 \(t'\) 能否通过交换两个字符的操作而得到所有给定串,其充要条件为对于每个串,\(t'\) 与其不同的位置个数为 \(2\),或两者相同且串内存在重复字符。当然,每种字符个数对于每个串都相等也是必要的。由于 \(t'\) 和 \(t\) 最多只差了两个字符,所以不需要对于每个解都进行 \(O(nk)\) 的暴力判定,预处理出 \(t\) 跟其它串的不同位置个数,对于每个 \(t'\),计算交换带来的贡献即可。
时间复杂度 \(O(n^2k)\)。
代码
/*
*/
#include <bits/stdc++.h>
#define eps 0.0000000001
using namespace std;
typedef long long ll;
typedef unsigned ui;
typedef pair<ll, ll> pii;
const int N = 5e3 + 5, M = 200000 + 5, P = 450, mod = 1e9 + 7, mod2 = 1e9 + 7, b1 = 131;
string s[N];
int dif[N],cnt[N][30];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int k,n;
cin>>k>>n;
for(int i=1;i<=k;i++){
cin>>s[i];
}
bool f = false;
for(int j=0;j<n;j++){
cnt[1][s[1][j] - 'a']++;
if(cnt[1][s[1][j] - 'a'] > 1){
f = true;
}
}
for(int i=2;i<=k;i++){
for(int j=0;j<n;j++){
dif[i] += s[1][j] != s[i][j];
cnt[i][s[i][j] - 'a']++;
}
for(int j=0;j<26;j++){
if(cnt[i][j] != cnt[1][j]){
cout<<-1;
return 0;
}
}
}
string t = s[1];
for(int i=0;i<n;i++){
for(int j=i + 1;j<n;j++){
bool flag = true;
for(int l=1;l<=k;l++){
int d = dif[l];
if(t[i] != s[l][i]) d--;
if(t[j] != s[l][j]) d--;
if(t[i] != s[l][j]) d++;
if(t[j] != s[l][i]) d++;
flag &= d == 2 || d == 0 && f;
}
if(flag){
swap(t[i],t[j]);
cout<<t;
return 0;
}
}
}
cout<<-1;
return 0;
}

浙公网安备 33010602011771号