E-小红的字符串重排

看的@Silencer76大佬题解(在吐槽区),用c++再写了一遍,写了非常详细的注释,面向像我一样的小白

(┭┮﹏┭┮)

具体思路请看代码

//		https://ac.nowcoder.com/acm/contest/92662/E
//		*	*	*	*
//		字符串重排

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;

int t,n;
void solve(){
	string s;
	cin>>s;
	n=s.size();
	int cnt[500];
	memset(cnt,0,sizeof(cnt));
	int mx=0;
	vector<pair<char, int>>v(n);
	vector<char> ans(n);
	for(int i=0;i<n;i++)
	{
		v[i].first=s[i],v[i].second=i;//v的key存字母,value存下标,而v的下标是0,1,2... n-1
		cnt[s[i]]++;//计数,记录每种字母的数量
		mx=max(mx,cnt[s[i]]);
	}
	if(mx>n/2)//最大的重复字母的数量不能大于s的长度的一半
	{
		cout<<-1<<endl;
		return ;
	}
	//按字母顺序排序,排完序后v按字典序的顺序排列,相同的字母挨在一起,但是字母对应的下标也会跟着变,因为这是键值对
	sort(v.begin(), v.end(), [](const pair<char,int>&v1, const pair<char,int>&v2){return v1.first<v2.first;});
	for(int i=0;i<n;i++)
	{
		//cout<<v[i].second<<" "<<v[(i+mx)%n].first<<endl;
		ans[v[i].second]=v[(i+mx)%n].first;//v[i].second为字母的下标,ans记录为该下标(v[i].second)对应的新的字母,就是v[(i+m)%n]位置的字母
	}
	cout<<string(ans.begin(), ans.end())<<endl;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	t=1;
	//cin>>t;
	while(t--){
		solve();
	}
	return 0;
}

//例如:dbddbbe
//对v排完序之后是这样的:
// 0 ->  b-1	
// 1 ->  b-4
// 2 ->  b-5

// 3 ->  d-0
// 4 ->  d-2
// 5 ->  d-3
// 6 ->  e-6

//	   字母下标	  	     mx为最大的相同字母的数量
//ans[v[i].second()]   =   v[(i+mx)%n].first
//ans:下标 1 存 d-0 对应的的字母 d
//	   下标 4 存 d-2 对应的的字母 d
//	   下标 5 存 d-3 对应的的字母 d
//	   下标 0 存 e-6 对应的的字母 e
//		......