題目描述:
小 B 表演魔法。
觀衆給他兩個 字符串 S,T,這兩個字符串中只包含 小寫 字母。
現在小 B 可以把兩個字符串中任意所有的字母 x 替換成 y( x,y 代表任意字母),記爲一次魔法操作。
注:任意所有指的是任何一種字母,它在兩個串中的所有出現的位置都可以替換成同一種字母,當然也可以替換它們中的幾個。
觀衆想知道,將兩個字符串變爲全等的最少操作次數是多少?
小 B 只會變魔術,所以他想讓你求出這個次數。
注:全等指對於任意的 1≤i≤n,都有 S[i]=T[i]。 (字符串座標從 1 開始)
輸入描述:
第一行一個整數 n,表示字符串的長度。
接下來的兩行,每行一個長度爲 n 的字符串,即 S 和 T。
對於 30% 的數據,1≤n≤10。
對於 70% 的數據,1≤n≤103。
對於 100% 的數據,1≤n≤105。
輸出描述:
一行一個整數,表示最少的操作次數。
輸入樣例:
3
aab
zcb
輸出樣例:
2
核心思想:
並查集。26個字母,初始祖先均爲自己。
對於1≤i≤n,如果s[i]!=t[i],則將兩者並在一起,ans++。
代碼如下:
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
const int N=1e5+20,M=32;
int pre[M],num[M];
char s[N],t[N];
int find(int x)
{
if(pre[x]==x)
return x;
return pre[x]=find(pre[x]);
}
int merge(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx==fy) return 0;
if(num[fx]>num[fy])
{
pre[fy]=fx;
num[fx]+=num[fy];
}
else
{
pre[fx]=fy;
num[fy]+=num[fx];
}
return 1;
}
int main()
{
int n,ans=0;
cin>>n;
scanf("%s%s",s,t);
for(int i=0;i<M;i++)
{
pre[i]=i;
num[i]=1;
}
for(int i=0;i<n;i++)
{
int x=s[i]-'a';
int y=t[i]-'a';
ans+=merge(x,y);
}
cout<<ans<<endl;
return 0;
}