zoukankan      html  css  js  c++  java
  • 优美的回文串--全国模拟(二)

    [编程题] 优美的回文串
    时间限制:1秒
    空间限制:32768K
    牛牛在书上看到一种字符串叫做回文串,当一个字符串从左到右和从右到左读都是一样的,就称这个字符串为回文串。牛牛又从好朋友羊羊那里了解到一种被称为优美的回文串的字符串,考虑一个长度为N只包含大写字母的字符串,写出它所有长度为M的连续子串(包含所有可能的起始位置的子串,相同的子串也要计入),如果这个字符串至少有K个子串都是回文串,我们就叫这个字符串为优美的回文串。现在给出一个N,牛牛希望你能帮他计算出长度为N的字符串有多少个是优美的回文串(每个位置都可以是'A'~'Z'的一个。) 
    输入描述:
    输入数据包括三个整数N, M, K(2 ≤ N ≤ 11, 2 ≤ M ≤ N, 0 ≤ K ≤ 11).
     
     
    输出描述:
    输出一个整数,表示所求的字符串个数.
     
    输入例子:
    2 2 1
     
    输出例子:
    26 长度为2的字符串,它长度为2的子串只有它自身。长度为2的回文串有"AA","BB","CC"..."ZZ",一共26种。
     1 #include <cstdio>
     2 //定义P(26,i)代表使用i个字母所组成的每位互不相同的全排列,fac[0]=P(26,0)代表用了一个字母每位都不相同的全排列(=26种),fac[1]=P(26,1)代表用了2个字母每位都不相同的全排列(=650种),.....
     3 long long fac[27], res;
     4 int n, m, k, a[12];//定义数组a为一种模式,a中a[i]与a[j]相同代表两个位置处为同一字符
     5 
     6 bool ok(int from) {
     7   for (int i = 0; i < m / 2; ++i) {
     8     if (a[from + i] != a[from + m - i - 1]) {
     9       return false;
    10     }
    11   }
    12   return true;
    13 }
    14 
    15 bool ok() {
    16   int cnt = 0;
    17   for (int i = 0; i <= n - m; ++i) {
    18     if (ok(i)) {
    19       ++cnt;
    20     }
    21   }
    22   return cnt >= k;
    23 }
    24 //num代表在n长度的字符串上用了几种不同的字母,num=0为用了1种,比如AAA,BBB;num=1为用了2种,比如ABA,CCB,依此类推(所有例子的n都为3),注意,这里都是模式匹配!
    25 //pos代表当前是第几个字符完成了模式填充
    26 void dfs(int pos, int num) {
    27   if (pos == n) {
    28     if (ok()) {
    29       res += fac[num];//a模式下,有num个位置必须不同,其它的位置都只有按照(check后的可行的)模式匹配的1种选择,所以直接+即可
    30     }
    31   } else {
    32     //当前pos位置有num个数字可用,枚举当前层num种可能性,下一层会继续枚举穷尽
    33     //i<num,所以下面这个循环会枚举出(....,[0 - (n - 1)],[0 - n],....)的所有模式,例:{0, 0, 0},{0, 0, 1}
    34     //要注意的是,枚举模式{0, 0, 1},{0, 0, 2}表达的意思是一样的,所以下一层处理的不同字母数应该与当前层相同,即num不变
    35     for(int i = 0; i < num; i++) {
    36       a[pos] = i;
    37       dfs(pos + 1, num);
    38     }
    39     //pos位置的最后一个枚举,下一层会枚举出(....,[n],[0 - (n + 1)],....)的所有模式,例:{0, 1, 0}, {0, 1, 1},{0, 1, 2},这样可以做到模式的不重复和不遗漏
    40     a[pos] = num;
    41     dfs(pos + 1, num + 1);
    42   }
    43 }
    44 
    45 int main() {
    46   scanf("%d%d%d", &n, &m, &k);
    47   fac[0] = 1;
    48   for (int i = 1; i <= 26; ++i) {
    49     fac[i] = fac[i - 1] * (27 - i);
    50   }
    51   dfs(0, 0);
    52   printf("%lld
    ", res);
    53 }

    参考:http://blog.csdn.net/scruelt/article/details/65940130?locationNum=1&fps=1

  • 相关阅读:
    前端构建工具gulpjs的使用介绍及技巧(转载)
    jq checked 设置问题
    JavaScript面向对象及相关知识
    github 操作指南
    WebStorm常用快捷键
    Windows下Scala环境搭建
    For与Function进阶实战、Lazy的使用笔记总结
    第3课 Scala函数式编程彻底精通及Spark源码阅读笔记
    第2课 Scala面向对象彻底精通及Spark源码SparkContext,RDD阅读总结
    第1课 Scala入门与实战笔记总结
  • 原文地址:https://www.cnblogs.com/qqky/p/7008824.html
Copyright © 2011-2022 走看看