zoukankan      html  css  js  c++  java
  • 51nod1464(trie + dfs)

    题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1464

    题意: 中文题诶~

    思路: 将所有半回文串构建成一棵字典树, 再 dfs 里面字典序第 k 大的字符串.

    注意插入半回文串时不能完全暴力插入, 不然插入的时间复杂度为 O(n^3), 会 tle. 可以先用 dp 预处理一下, dp[i][j] 存储 子串[i, j] 是否为回文串, vis[i] 记录以 i 开头的最长半回文串末尾位置. 那么插入时可以每次插入 [i, vis[i]] 之间的所有半回文串, 时间复杂度为 O(n^2). 然后再 dfs 一下答案即可.

    代码:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 using namespace std;
     5 
     6 const int MAXN = 5e3 + 10;
     7 int trie[MAXN * MAXN][2], num[MAXN * MAXN], id = 1;
     8 bool dp[MAXN][MAXN];//dp[i][j]存储[i,j] 是否为半回文串
     9 int vis[MAXN];//vis[i]存储以i开始的最长半回文串末尾位置
    10 char s[MAXN];
    11 
    12 void init(int len){
    13     for(int i = len - 1; i >= 0; i--){
    14         vis[i] = i;
    15         dp[i][i] = true;
    16         for(int j = i + 1; j < len; j++){
    17             if(s[i] == s[j]){
    18                 if(i + 2 >= j - 2) dp[i][j] = true;
    19                 else dp[i][j] = dp[i + 2][j - 2];
    20             }
    21             if(dp[i][j]) vis[i] = j;
    22         }
    23     }
    24 }
    25 
    26 void insert(int st){
    27     int node = 0;
    28     for(int i = st; i <= vis[st]; i++){
    29         int cnt = s[i] - 'a';
    30         if(!trie[node][cnt]) trie[node][cnt] = id++;
    31         if(dp[st][i]) num[trie[node][cnt]]++;
    32         node = trie[node][cnt];
    33     }
    34 }
    35 
    36 int k;
    37 string sol;
    38 
    39 void dfs(int x){
    40     string cnt = sol;
    41     if(k > 0 && trie[x][0]){
    42         sol += 'a';
    43         k -= num[trie[x][0]];
    44         dfs(trie[x][0]);
    45     }
    46     if(k > 0 && trie[x][1]){
    47         sol = cnt;
    48         sol += 'b';
    49         k -= num[trie[x][1]];
    50         dfs(trie[x][1]);
    51     }
    52 }
    53 
    54 int main(void){
    55     scanf("%s%d", s, &k);
    56     int len = strlen(s);
    57     init(len);
    58     for(int i = 0; i < len; i++){
    59         insert(i);
    60     }
    61     dfs(0);
    62     cout << sol << endl;
    63     return 0;
    64 }
    View Code
  • 相关阅读:
    换行的展示
    jsp页面的导出功能
    怎么设置回车键为提交功能?
    HBuilder使用心得
    js和jQuery
    前端常用技术总结--java程序员
    对压缩文件加密
    删除表中一个字段的SQL语句
    用NPOI操作EXCEL-锁定列CreateFreezePane()
    MVC 点击下载文档
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/7672490.html
Copyright © 2011-2022 走看看