虽然这题用排序可以轻松搞定,但是我们可以考虑用二分匹配,在 O(n2) 的时间内得到答案。
将两个字符串中每个字母的数目进行统计,然后得到一个有 26 对结点的二分图,对二分图跑一次最大匹配,当且仅当最大匹配数等于 26 的时候,输出 YES,否则输出 NO。
二分版本的代码,运用匈牙利算法实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| #include <cstdio> #include <cstdlib> #include <cstring> using namespace std;
const int MAX = 27;
int n, m; int pre[MAX]; bool visit[MAX]; bool conn[MAX][MAX];
void init() { memset(conn, 0, sizeof(conn)); memset(pre, -1, sizeof(pre)); }
bool dfs(int a) { for (int i = 0; i < n; i++) { if (conn[a][i] == 1 && !visit[i]) { visit[i] = true; if (pre[i] == -1 || dfs(pre[i])) { pre[i] = a; return true; } } } return false; }
int BinaryMatch() { int ans = 0; for (int i = 0; i < n; i++) { memset(visit, 0, sizeof(visit)); if (dfs(i)) ans++; } return ans; }
int main() { char str[105]; int a[26] = {0}, b[26] = {0}, len; init(); gets(str); len = strlen(str); for (int i = 0; i < len; i++) a[str[i] - 'A']++; gets(str); len = strlen(str); for (int i = 0; i < len; i++) b[str[i] - 'A']++; for (int i = 0; i < 26; i++) for (int j = 0; j <= 26; j++) if (a[i] == b[j]) conn[i][j] = true; else conn[i][j] = false; n = 26; if (BinaryMatch() == n) printf("YES\n"); else printf("NO\n"); return 0; }
|