题解: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;
}
posted @ 2025-08-19 17:29  cqbzcjh  阅读(7)  评论(0)    收藏  举报