题解:AT_abc345_c [ABC345C] One Time Swap
分析
先假设答案为所有字母都不同时的答案,再减去相同字母对的个数来排除重复的答案。
我们可以发现,除非交换的两个是相同的字母,否则交换后的结果一定和原字符串和其他交换后的结果不同(可以自己试一试)。
所以要用 \(n\times(n-1)\div2\) 来求长度为 \(n\) 时所有字母都不同时的答案和有 \(n\) 个相同字母时的相同字母对的个数。
注意相同字母交换后的结果虽然和原字符串相同,但也是一种结果,仍然加进答案里。
Code
#include<bits/stdc++.h>
using namespace std;
string s;
long long h[30],l,ans;//防止溢出,也可以在计算时乘以1LL
int main(){
ios::sync_with_stdio(NULL);
cin.tie(NULL);cout.tie(NULL);
cin>>s;
l=s.size();
ans=l*(l-1)/2;//所有字母不同时的答案
for(int i=0;i<l;i++)
h[s[i]-'a']++;//通过桶记录相同字母的个数
int t=0;
for(int i=0;i<26;i++){
if(h[i]){
ans-=h[i]*(h[i]-1)/2;//减去相同字母的对数
if(h[i]>1)t=1;
}
}
if(t)ans++;
//加上结果为原字符串的情况
cout<<ans;
return 0;
}

浙公网安备 33010602011771号