链接:http://vjudge.net/problem/viewProblem.action?id=19602

描述:给出一个字符串,求重新排列后第n个回文串,若没有则输出”XXX“。

思路:组合数问题。

首先考虑什么时候有回文串。很简单,数量为奇数的字母不超过1个。且这个字母只能是在字符串的中间。

然后我们会发现,回文串的字典序就是字串前半部分的字典序。问题就转化成求字典序第n的字符串。于是我们可以试着模拟一下这个过程。首先把字典序最小的字母放在第一个位置,然后计算出后面字母的排列数,即固定下第一个位置后有多少种字符串,设这个数是Num。如果Num>=n,则第一个位置就确定了,继续考虑第二个位置;如果Num<n,则第一个位置的字母不合适,n-=Num,更换成字典序第二的字母,重复上述计算。如果一直是Num<n,则无解。

PS.zyy的数学不好,说得有点啰嗦,请各位大神不吝指教~

下面是我的实现:

  1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <cmath>
5 using namespace std;
6 #define MaxLen 30
7 int T,N;
8 int Cnt[30],Lit;
9 char str[MaxLen+5],Ans[MaxLen+5];
10 bool flag;
11 inline int fac(int t)
12 {
13 if(t<=2)
14 return t;
15 int i,Ret=1;
16 for(i=2;i<=t;i++)
17 Ret*=i;
18 return Ret;
19 }
20 inline int Arg()
21 {
22 int i,Sum=0;
23 for(i=1;i<=26;i++)
24 {
25 if(!Cnt[i])
26 continue;
27 Sum+=Cnt[i];
28 }
29 Sum=fac(Sum);
30 for(i=1;i<=26;i++)
31 {
32 if(!Cnt[i])
33 continue;
34 Sum/=fac(Cnt[i]);
35 }
36 return Sum;
37 }
38 void Work(int pos,int n)
39 {
40 int i,Num;
41 for(i=1;i<=26;)
42 {
43 if(!Cnt[i])
44 {
45 i++; continue;
46 }
47 Cnt[i]--;
48 Num=Arg();
49 if(Num==0)
50 {
51 Ans[pos]='a'+i-1;
52 return;
53 }
54 else if(Num<n)
55 {
56 Cnt[i]++;
57 i++;
58 n-=Num;
59 }
60 else
61 {
62 Ans[pos]='a'+i-1;
63 Work(pos+1,n);
64 return;
65 }
66 }
67 flag=false;
68 }
69 int main()
70 {
71 int Len,i,JS;
72 scanf("%d",&T);
73 for(int t=1;t<=T;t++)
74 {
75 printf("Case %d: ",t);
76 scanf("%s",str); scanf("%d",&N);
77 Len=strlen(str); Lit=(Len+1)/2;
78 if(Len==1)
79 {
80 if(N==1)
81 printf("%s\n",str);
82 else
83 printf("XXX\n");
84 continue;
85 }
86 memset(Cnt,0,sizeof(Cnt));
87 for(i=0;i<Len;i++)
88 Cnt[str[i]-'a'+1]++;
89 JS=0;
90 for(i=1;i<=26;i++)
91 {
92 if(Cnt[i]%2)
93 {
94 JS++;
95 Ans[Lit]='a'+i-1;
96 }
97 Cnt[i]/=2;
98 }
99 if(JS>=2)
100 {
101 printf("XXX\n");
102 continue;
103 }
104 flag=true;
105 Work(1,N);
106 if(!flag)
107 printf("XXX\n");
108 else
109 {
110 for(i=1;i<=Lit;i++)
111 printf("%c",Ans[i]);
112 if(Lit*2==Len)
113 for(i=Lit;i>=1;i--)
114 printf("%c",Ans[i]);
115 else
116 for(i=Lit-1;i>=1;i--)
117 printf("%c",Ans[i]);
118 printf("\n");
119 }
120 }
121 return 0;
122 }

[题解]UVA11027 Palindromic Permutation的更多相关文章

  1. 【题解】CF359B Permutation

    [题解]CF359B Permutation 求一个长度为\(2n\)的序列,满足\(\Sigma |a_{2i}-a_{2i-1}|-|\Sigma a_{2i}-a_{2i-1}|=2k\) 这种 ...

  2. LeetCode(3)题解: Longest Palindromic Substring

    https://leetcode.com/problems/longest-palindromic-substring/ 题目: Given a string S, find the longest ...

  3. LeetCode题解——Longest Palindromic Substring

    题目: 给定一个字符串S,返回S中最长的回文子串.S最长为1000,且最长回文子串是唯一. 解法: ①遍历,对于每个字符,计算以它为中心的回文子串长度(长度为奇数),同时计算以它和右边相邻字符为中心的 ...

  4. UVA 11027 - Palindromic Permutation

    题目意思为解码字符串,要输出第n个回文字符串,因为对称关系,前一半确定了,后一半也就跟着确定了,所以n其实就是前一半字符串的编码,还要减去1,直接解码出来再复制给后半即可 #include<cs ...

  5. LeetCode题解之Palindromic Substrings

    1.问题描述 2.问题分析 对于每一个字符,以该字符为中心计算回文个数. 3.代码 int countSubstrings(string s) { ; ) ; ; i < s.size(); i ...

  6. PAT甲题题解-1024. Palindromic Number (25)-大数运算

    大数据加法给一个数num和最大迭代数k每次num=num+num的倒序,判断此时的num是否是回文数字,是则输出此时的数字和迭代次数如果k次结束还没找到回文数字,输出此时的数字和k 如果num一开始是 ...

  7. leetcode个人题解——#31 Next Permutation

    写这题时脑子比较混乱,重写了一遍wiki大佬的解法. 算法: According to Wikipedia, a man named Narayana Pandita presented the fo ...

  8. LeetCode Palindrome Permutation II

    原题链接在这里:https://leetcode.com/problems/palindrome-permutation-ii/ 题目: Given a string s, return all th ...

  9. 267. Palindrome Permutation II

    题目: Given a string s, return all the palindromic permutations (without duplicates) of it. Return an ...

随机推荐

  1. rocketmq实现延迟队列精确到秒级实现方案1-代理实现

    简单的来说,就是rocketmq发送消息到broker的时候,判断是否定时消息, 如果是定时消息,将消息发送到代理服务(这个是一个独立的服务,需要自己开发,定时地把消息发送出去), 当然了消息用什么来 ...

  2. Android 12(S) 图形显示系统 - 示例应用(二)

    1 前言 为了更深刻的理解Android图形系统抽象的概念和BufferQueue的工作机制,这篇文章我们将从Native Level入手,基于Android图形系统API写作一个简单的图形处理小程序 ...

  3. codeblocks中报错:'to_string' was not declared in this scope解决方案

    在windows下使用codeblocks(编译器采用MinGW)时,有时会遇到"'to_string' was not declared in this scope"的错误,这里 ...

  4. Cesium中级教程9 - Advanced Particle System Effects 高级粒子系统效应

    Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ 要了解粒子系统的基础知识,请参见粒子系统入门教程. Weathe ...

  5. golang中的原子操作atomic包

    1. 概念 原子操作 atomic 包 加锁操作涉及到内核态的上下文切换,比较耗时,代价高, 针对基本数据类型我们还可以使用原子操作来保证并发的安全, 因为原子操作是go语言提供的方法,我们在用户态就 ...

  6. gin中绑定表单数据至自定义结构体

    package main import "github.com/gin-gonic/gin" type StructA struct { FieldA string `form:& ...

  7. windows根据进程id杀死任务进程

    然后打开任务管理器找出来结束进程即可

  8. How to find out which process is listening upon a port

    When we covered port scanning a short while ago we discovered how to tell which ports had processes ...

  9. ApacheCN Java 译文集 20211012 更新

    Effective Java 中文第三版 1. 考虑使用静态工厂方法替代构造方法 2. 当构造方法参数过多时使用 builder 模式 3. 使用私有构造方法或枚类实现 Singleton 属性 4. ...

  10. 【转】C# / Extension 扩展方法

    扩展方法简介扩展方法使你能够向现有类型"添加"方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调 ...