【CodeForces - 124C】Prime Permutation(数学,思维,小结论)
題干:
You are given a string?s, consisting of small Latin letters. Let's denote the length of the string as?|s|. The characters in the string are numbered starting from?1.
Your task is to find out if it is possible to rearrange characters in string?s?so that for any prime number?p?≤?|s|?and for any integer?i?ranging from?1?to?|s|?/?p(inclusive) the following condition was fulfilled?sp?=?sp?×?i. If the answer is positive, find one way to rearrange the characters.
Input
The only line contains the initial string?s, consisting of small Latin letters (1?≤?|s|?≤?1000).
Output
If it is possible to rearrange the characters in the string so that the above-mentioned conditions were fulfilled, then print in the first line "YES" (without the quotes) and print on the second line one of the possible resulting strings. If such permutation is impossible to perform, then print the single string "NO".
Examples
Input
abcOutput
YES abcInput
abcdOutput
NOInput
xxxyxxxOutput
YES xxxxxxyNote
In the first sample any of the six possible strings will do: "abc", "acb", "bac", "bca", "cab" or "cba".
In the second sample no letter permutation will satisfy the condition at?p?=?2?(s2?=?s4).
In the third test any string where character "y" doesn't occupy positions 2, 3, 4, 6 will be valid.
題目大意:
給你一個字符串(len<=1000),讓你找到它的另一個排列,使得任意一個素數(shù)的倍數(shù)的位置上的字符相同。
解題報告:
先說正解:不難發(fā)現(xiàn),除了1和大于len/2的素數(shù)??其他都需要是同一個數(shù)。
證明如下:對于小于等于len/2的數(shù),如果他是合數(shù),那肯定要和2位置上的字符相同,如果他是素數(shù),假設(shè)為p,那他要和2*p的位置相同,而2*p的位置和2的相同,所以也要相同。對于大于len/2的數(shù),顯然。
再說另一種做法:并查集,最直觀的想法,但是實(shí)現(xiàn)的時候有個問題,見下面的代碼,如果加上getf那一行循環(huán),對于len==20左右的時候就GG,直接在下面cmp1那個排序中死循環(huán),不知道為什么。
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<stack> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define FF first #define SS second #define ll long long #define pb push_back #define pm make_pair using namespace std; typedef pair<int,int> PII; const int MAX = 2e5 + 5; char s[MAX]; bool is[MAX]; int n; struct Node {char ch;int cnt;bool operator<(const Node & b) const {return cnt < b.cnt;} } R[MAX]; struct NNode {int f,num,id; } W[MAX],WW[MAX]; bool cmp1(NNode a,NNode b) {if(a.f == b.f) return 1;else return WW[a.f].num < WW[b.f].num; } bool cmp2(NNode a,NNode b) {return a.id < b.id; } int getf(int v) {return W[v].f == v ? v : W[v].f = getf(W[v].f); } void merge(int u,int v) {int t1 = getf(u),t2=getf(v);if(t1 == t2) return;W[t2].f = t1;W[t1].num += W[t2].num; } void init() {memset(is,1,sizeof is);is[0]=is[1]=0;for(int i = 2; i<=n; i++) {if(is[i] == 0) continue;for(int j = i+i; j<=n; j+=i) {is[j] = 0;merge(i,j);}} } char ans[MAX]; int main() { for(char i = 'a'; i<='z'; i++) R[i].ch=i,R[i].cnt=0; scanf("%s",s+1); n = strlen(s+1);for(int i = 1; i<=n; i++) W[i].f=i,W[i].num=1,W[i].id=i,R[s[i]].cnt++; init();sort(R+'a',R+'z'+1); // for(int i = 1; i<=n; i++) getf(i);for(int i = 1; i<=n; i++) WW[i]=W[i];sort(W+1,W+n+1,cmp1);int cur = 'a',flag=1;//注意cur只代表ascll碼,不代表此時字符就是a字符,因?yàn)槟阋呀?jīng)排序了 for(int i = 1; i<=n; i++) {while(R[cur].cnt == 0 && cur <= 'z') cur++;if(cur == 'z'+1) {flag=0;break; }ans[W[i].id] = R[cur].ch;R[cur].cnt--;}sort(W+1,W+n+1,cmp2);//排序還原回原序列 使得和getf可以對應(yīng)上for(int i = 1; i<=n; i++) {if(ans[i] != ans[getf(i)]) flag = 0; }if(flag == 0) {puts("NO");return 0;}puts("YES");printf("%s",ans+1);return 0 ; }?
總結(jié)
以上是生活随笔為你收集整理的【CodeForces - 124C】Prime Permutation(数学,思维,小结论)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2017年6/7/8月广发信用卡新户满额
- 下一篇: Mac下使用brew的常用步骤