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

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

思路:组合数问题。

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

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

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

下面是我的实现:

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

    问题描述 给定一个由 '(' 和 ')' 括号组成的字符串 S,我们需要添加最少的括号( '(' 或是 ')',可以在任何位置),以使得到的括号字符串有效. 从形式上讲,只有满足下面几点之一,括号字符 ...

  2. 【Kafka】基于Windows环境的Kafka有关环境(scala+zookeeper+kafka+可视化工具)搭建、以及使用.NET环境开发的案例代码与演示

    前言:基于Windows系统下的Kafka环境搭建:以及使用.NET 6环境进行开发简单的生产者与消费者的演示. 一.环境部署 Kafka是使用Java语言和Scala语言开发的,所以需要有对应的Ja ...

  3. Ansible + shell 实现部署fastdfs+nginx 实现图片服务器并提供动态缩放功能;

    因为公司阿里服务器变动几次,手动部署了好几次fastdfs+nginx,于是就想到了自动化部署,以下为脚本内容,由于只是想把着功能实现,并未有完完整的判断逻辑: 以下为ansible-playbook ...

  4. IntelliJ IDEA 热部署,修改java文件 不用重启tomcat

    详情见大佬:https://www.cnblogs.com/chenweichu/articles/6838842.html

  5. NGINX的动静分离;什么是负载均衡

    目录 一:动静分离 二:负载均衡 一:动静分离 动静分离是指在 web 服务器架构中,将静态页面与动态页面或者静态内容接口和动态内容接口分开不同系统访问的架构设计方法,进而提示整个服务的访问性和可维护 ...

  6. SP419/422 TRANSP(2) - Transposing is Fun

    首先可以发现转置本质上就是一个置换,问题就转化为求一个排列排成有序的最少次数. 这是一个经典问题,答案为点数减循环置换的个数,考虑如何求循环置换. 发现有两个特殊性质:置换为转置,矩阵的边长为 \(2 ...

  7. Web3对于我们普通人意味着什么?

    ▲ 点击101链视界,关注不走丢 大家好,我是阿创,这是我的第27篇原创文章. 上一篇文章中我们了解了互联网的前世今生:Web 1.0.2.0.3.0,我们对Web的前两个阶段都不陌生,特别是 Web ...

  8. application/x-www-form-urlencoded、application/json、multipart/form-data、text/xml简单总结

    最近在数据传输时,一直不明白这四种的区别,查了很多资料,也还是感到很模糊,因此,简单总结一下,以后再完善 1.在GET方式传输数据中,这四种格式,后台都可以接收数据(原生的request.getPar ...

  9. foreEach 跳出循环

    const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; const _ = require('lodash'); let outArr = []; try { arr. ...

  10. JDK版本基础知识解释

    感谢大佬:https://www.cnblogs.com/bjguanmu/articles/8710209.html jdk:java development kit,是程序员编写java程序需要的 ...