题意:
给你k个串,每个串长度都是n,现在问你是否可能这些串是同一个串交换两个位置的字符所产生的,输出这个原串。
k <= 2500, n <= 5000, k * n <= 5000
题解:
一开始我想的是,对k个串,全部n^2交换一下,然后hash存在map里面,看哪些串出现了k次,这些串是可以的,
但是复杂度是,还是不能过。
然后我想,只要对第一个串进行交换即可,但是交换以后对每个串又要用
时间计算差别,复杂度是
。
其实计算差别可以用O(1)时间,只要预处理一下所有串与s[1]的差别即可,所以复杂度是
s1交换两字符后,如果这个是原串,那么后面的串与他的差别要么是2,要么是0,并且可以是0的条件是原串存在两个相同字符。
原串存在的必要条件还有这k个串字符集相同。
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <bitset>
#include <map>
#include <vector>
#include <stack>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <cmath>
#ifdef LOCAL
#define debug(x) cout<<#x<<" = "<<(x)<<endl;
#else
#define debug(x) 1;
#endif
#define chmax(x,y) x=max(x,y)
#define chmin(x,y) x=min(x,y)
#define lson id<<1,l,mid
#define rson id<<1|1,mid+1,r
#define lowbit(x) x&-x
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, int> pii;
const ll MOD = 1e9 + 7;
const double eps = 1e-10;
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fll;
const int MAXN = 5e3 + 5;
char s[MAXN][MAXN];
int num[MAXN][26];
int dif[MAXN];
int dif2[MAXN];
int main() {
#ifdef LOCAL
freopen ("input.txt", "r", stdin);
#endif
int k, n;
int f = 0, ok = 1;
scanf ("%d %d", &k, &n);
for (int i = 1; i <= k; i++) scanf ("%s", s[i]);
for (int i = 1; i <= k; i++) {
for (int j = 0; j < n; j++) num[i][s[i][j] - 'a']++;
for (int j = 0; j < 26; j++) if (num[i][j] != num[1][j]) ok = 0;
}
if (!ok) return 0 * puts ("-1");
for (int i = 0; i < 26; i++) if (num[1][i] > 1) f = 1;
for (int i = 2; i <= k; i++)
for (int j = 0; j < n; j++)
if (s[i][j] != s[1][j]) dif[i]++;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int can = 1;
for (int l = 2; l <= k; l++) dif2[l] = dif[l];
for (int l = 2; l <= k; l++) {
if (s[1][i] != s[l][i]) dif2[l]--;
if (s[1][j] != s[l][i]) dif2[l]++;
if (s[1][j] != s[l][j]) dif2[l]--;
if (s[1][i] != s[l][j]) dif2[l]++;
if (dif2[l] != 2) {
if(!f || dif2[l] != 0) can = 0;
}
}
if(can) {
swap(s[1][i], s[1][j]);
return 0 * printf("%s\n", s[1]);
}
}
}
puts("-1");
return 0;
}