题目大意:

As a token of his gratitude, Takahashi has decided to give Snuke a level-KK palindrome. A level-LL palindrome, where LL is a non-negative integer, is defined as follows:

  • Let rev(s)rev(s) denote the reversal of a string ss.
  • A string ss is said to be a palindrome when s=rev(s)s=rev(s).
  • The empty string and a string that is not a palindrome are level-00 palindromes.
  • For any non-empty level-(L−1)(L−1) palindrome tt, the concatenation of t,rev(t)t,rev(t) in this order is a level-LL palindrome.
  • For any level-(L−1)(L−1) palindrome tt and any character cc, the concatenation of t,c,rev(t)t,c,rev(t) in this order is a level-LL palindrome.

Now, Takahashi has a string SS. Determine whether it is possible to make SS an exactly level-KK palindrome by doing the following action zero or more times: choose a character in SS and change it to another lowercase English letter. If it is possible, find the minimum number of changes needed to make SS a level-KK palindrome.

(自己翻译去)

题目思路:

粗略分析:

通过“最少改变”这个关键词,我们不难想到贪心算法。

对于本道题,我们的贪心策略是:
找到字母相同的位置,用桶统计这个集合中每个字母出现的次数。

找到出现最多和次多的字母及最多出现的个数,

并将集合中的字母全部变成出现最多的那个字母,

同时统计答案。

问题细化:

Q1:如何找到必须相同的字母的位置?

A:使用分治算法,并用并查集来维护这个集合(并查集在替换操作上还有用处)

Q2:impossible情况

①k太大(大概是k>=20)

②len=pow(2,k)

③len<pow(2,k-1)

Q3:特殊判断!

1)替换后的字符串有更深层的回文。

这个时候记录下的次多的字母个数就有用处了。只需要掉一个非后回文串中心的字母就可以了。(要比较找最优方法)

并查集的性质也可以保证每个集合的总祖先是连续的处于字符串的头部的。非常方便进行替换操作。

2)特判:长度唯一的字符串回文深度为1

code:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=5e5+5;
  4. int k;
  5. string s;
  6. int ans=0;
  7. int b[N][30];//桶
  8. int maxn[N];//最大
  9. int emaxn[N];//次大
  10. int bel[N];//最小的子字符串中的字母
  11. int f[N];//并查集
  12. vector<int> res;//存最小子字符串的下标
  13.  
  14. int find(int x)//找祖先
  15. {
  16. if(f[x]==x) return x;
  17. return f[x]=find(f[x]);
  18. }
  19.  
  20. void h(int x,int y)//认祖先
  21. {
  22. f[find(x)]=find(y);
  23. return ;
  24. }
  25.  
  26. void dfs(int l,int r,int lev){//二分
  27. if(lev==k) return ;
  28. int len=(r-l+1);
  29. if(len%2==1){
  30. dfs(l,l+len/2-1,lev+1);dfs(l+len/2+1,r,lev+1);
  31. }
  32. if(len%2==0){
  33. dfs(l,l+len/2-1,lev+1);dfs(l+len/2,r,lev+1);
  34. }int mid=(l+r)/2;//奇回文串和偶回文串需要分开讨论
  35. for(int i=0;r-i>=mid;i++) h(r-i,l+i);//建立集合
  36. return ;
  37. }
  38.  
  39. bool judge(int len){//判断是否为回文串
  40. for(int i=1;i<=len;i++) if(bel[i]!=bel[len-i+1]){return true;}
  41. return false;
  42. }
  43.  
  44. int main(){
  45. cin>>k>>s;
  46. int len=s.size();
  47. s=" "+s;
  48. if(k>=20||len/(1<<k)==1||len<(1<<(k-1))){puts("impossible");return 0;}//无解的判断
  49.  
  50. for(int i=1;i<=len;i++) f[i]=i;//并查集初始化
  51.  
  52. int dip=k;
  53. int anslen=len;//anslen表示最小子串的长度
  54.  
  55. while(dip--){
  56. anslen/=2;//计算最小子串的长度
  57. }
  58.  
  59. dfs(1,len,0);//二分
  60. for(int i=1;i<=len;i++){
  61. b[find(i)][s[i]-'a']++;
  62. if(find(i)==i) res.push_back(i);//res存的是一个完整的最小子串
  63. }
  64.  
  65. int sum=res.size();
  66.  
  67. for(int i=0;i<sum;i++){
  68. int x=res[i];
  69. for(int j=0;j<26;j++){
  70. if(b[x][j]>maxn[x]) {emaxn[x]=maxn[x];maxn[x]=b[x][j];bel[x]=j;}
  71. else emaxn[x]=max(emaxn[x],b[x][j]);//找最大和找次大
  72. }
  73. }
  74.  
  75. for(int i=0;i<sum;i++) ans+=maxn[res[i]];//统计ans
  76.  
  77. if(!anslen){cout<<len-ans;return 0;}//最小子串长度为1的特判
  78. if(!judge(anslen)){//包含更深的回文
  79. int minn=12345678;
  80. for(int i=1;i<=anslen;i++){
  81. if(anslen%2==1&&i==anslen/2+1) continue;
  82. minn=min(minn,maxn[i]-emaxn[i]);//寻找最佳替换方案
  83. }
  84. ans-=minn;
  85. }
  86. cout<<len-ans;
  87. return 0;
  88. }

E - Level K Palindrome的更多相关文章

  1. 【LeetCode】1400. 构造 K 个回文字符串 Construct K Palindrome Strings

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 统计奇数字符出现次数 日期 题目地址:https:// ...

  2. uva 122 trees on the level——yhx

    题目如下:Given a sequence of binary trees, you are to write a program that prints a level-order traversa ...

  3. 链表之求链表倒数第k个节点

    题目描述:输入一个单向链表,输出该链表中倒数第k个节点,链表的倒数第0个节点为链表的尾指针. 最普遍的方法是,先统计单链表中结点的个数,然后再找到第(n-k)个结点.注意链表为空,k为0,k为1,k大 ...

  4. E - Trees on the level

     Trees on the level  Background Trees are fundamental in many branches of computer science. Current ...

  5. 1101-Trees on the Level

    描述 Trees are fundamental in many branches of computer science. Current state-of-the art parallel com ...

  6. 设计一个算法,求非空二叉树中指定的第k层(k&gt;1)的叶子节点的个数

    思想:採用基于层序遍历的方法. 用level扫描各层节点,若某一层的节点出队后.rear指向该层中最右节点.则将rear赋值给last(对于第一层.last=1).在出队时,若front=last,表 ...

  7. UVA122-Trees on the level(链二叉树)

    Trees on the level Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Sub ...

  8. Trees on the level(指针法和非指针法构造二叉树)

    Trees on the level Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  9. hdu 1622 Trees on the level(二叉树的层次遍历)

    题目链接:https://vjudge.net/contest/209862#problem/B 题目大意: Trees on the level Time Limit: 2000/1000 MS ( ...

随机推荐

  1. vivo 官网资源包适配多场景的应用

    本文介绍了资源包的概念及使用场景,同时对资源包的几种使用方案进行对比.通过本文,大家可以快速掌握资源包的使用方法,解决单一配置满足多场景.多样式的问题. 一.业务背景 随着官网项目的业务深入发展,单纯 ...

  2. 聊聊Dotnet的垃圾回收

    最近在做一个项目,用到了大量的非托管技术,所以垃圾回收变得很重要.   在说垃圾回收之前,先说说两个概念: 托管代码,是由CLR管理的代码 非托管代码,是由操作系统直接执行的代码 在早期C++的时候, ...

  3. 干货满满-原来这才是hooks-React Hooks使用心得

    序言 ---最后有招聘信息哦-React是一个库,它不是一个框架.用于构建用户界面的Javascript库.这里大家需要认识这一点.react的核心在于它仅仅是考虑了如何将dom节点更快更好更合适的渲 ...

  4. 进阶宝典一|SqlServer数据库自动备份设置

    很多人都没机会接触到数据库备份,经常操作的要么是数据库管理员,要么是项目负责人.那是不是说数据库备份就不用学了? 不,其实作为开发人员应该要了解数据备份,数据备份的手段有很多:软件备份.脚本备份.其他 ...

  5. WebSocket与即时通讯

    HTTP 协议有一个缺陷:通信只能由客户端发起!HTTP 协议做不到服务器主动向客户端推送信息.这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦.我们只能使用"轮 ...

  6. Go Module实战:基于私有化仓库的GO模块使用实践

    新年开工近一月,2021 年第一期 Open Talk 定档 3 月 18 日晚 8 点,本期我们邀请到了又拍云资深后端开发工程师刘云鹏和我们一起聊聊 Go 最新特性 Go Module 实战. 刘云 ...

  7. url里bookmark是什么意思

    <a rel="bookmark" href="abc.com"> 点击查看 </a> rel 这个属性的全称是  relationsh ...

  8. EF Core 原理从源码出发(二)

    紧接着我的上一篇博客,上回分析到ef 一个重要的对象,changetracker这个对象,当我们向DbContext添加对象的时候我们会调用如下代码. 1 private EntityEntry< ...

  9. 扩展欧几里得算法(EXGCD)学习笔记

    0.前言 相信大家对于欧几里得算法都已经很熟悉了.再学习数论的过程中,我们会用到扩展欧几里得算法(exgcd),大家一定也了解过.这是本蒟蒻在学习扩展欧几里得算法过程中的思考与探索过程. 1.Bézo ...

  10. python实现顺序表

    python实现顺序表可以有两中形式进行存储 列表 元组 其实简单来说,顺序表无非就是操作列表和元组的方法来对顺序表进行操作. 实例代码 7 class SqList: 8 def __init__( ...