并查集,贪心
题目意思:
给出一个字符串 s, 长度 n <= 1000, 改变字符串的各个字母的顺序,使得:
下标是素数的位置(假设为p), s[p] = s[p * i], 1 <= i <= n / p
本题要点:
1、并查集:
把素数位p,满足条件 s[p] = s[p * i], 1 <= i <= n / p 的所有下标全部放到一个集合里面。
用一个结构体 来记录,然后按 size 从大到小排序.
struct node2 // p[i] 表示以i为父节点信息
{
int father;
int size;
};
2、统计每个字母的出现次数,按次数从大到小排序。
扫描集合数组p, 优先满足大集合。 每次都把出现次数最多的字母去分配给这个集合。分配完,减去分配了多少,
然后字母的出现次数再排序。
3、 用 vector[i] 统计 以i为 父节点的所有节点的集合。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int MaxN = 1010;
char s[MaxN];
int fa[MaxN], prime[MaxN], pNum;
bool vis[MaxN];
int n;
struct node1 //统计每个字母出现的次数
{
char ch;
int cnt;
bool operator<(const node1& rhs) const
{
if(cnt != rhs.cnt)
return cnt > rhs.cnt;
return ch < rhs.ch;
}
}nod[30];
struct node2 // p[i] 表示以i为父节点信息
{
int father;
int