*题解: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;
}
posted @ 2026-07-22 20:04  yutar  阅读(2)  评论(0)    收藏  举报