题目

题目大意

有一个字符串\(p\)。一开始字符串\(s\)为空串。
接下来进行若干次操作:在\(s\)的某个空隙中插入\(p\)。
给出操作后的\(s\),问长度最小的\(p\)。


思考历程

感觉是一道神仙题。
于是考虑暴力。
在\(s\)前面找连续的最长串,作为\(p\)的前缀。显然这个串中只出现过一次\(s_1\)
同样地,在后面也找一条,作为后缀。
将前缀出现的位置和后缀出现的位置标记一下。
统计每个字符出现的个数,求最大公因数\(g\),表明操作的次数为\(g\)的因数。
然后按照长度从小到大枚举子串,如果当前子串的头和尾都被标记了,并且中间的字符个数的比例和整个字符串的比例相等,就取这个字符串作为\(p\)暴力判断。
暴力判断的时候,每次用\(KMP\)找出一个子串,将它删去,递归。
如果有多个这样的子串,那就分别搞。

然而出现了某细节错误,导致只有\(10\)分。


正解

这题的正解居然是\(DP\)!
考虑一个字符串,它的所有元素会在后面的操作中逐渐分离,但是它们的相对顺序是不变的。
而且它原来相邻的两个元素在后面的操作之后,两个元素之间的空间可以转化成个子问题。如果可行,则这个子问题也必定可行。
先考虑普通的\(DP\)思路:\(f_{l,r,k}\)表示区间\([l,r]\)中,有零散的\(k\)个字母拼起来等于\(p_{1..k}\),其它的都合法,是否可行。
转移有两种:一种是从\(f_{l,r-1,k-1}\)转移过来,条件是\(s[j]=p[k]\),就是加上一个零散的元素。
另一种是从\(f_{l,j,k} \ and \ f_{j,r,0}\),就是在后面拼一个合法的。
然而这样会\(TLE\)。
紧接着我们发现,实际上,\(k=(r-l+1)\mod len\)
所以就可以省去一维,然后就可以\(AC\)了。


代码

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
#define N 210
inline int gcd(int a,int b){while (b){int k=a%b;a=b;b=k;}return a;
}
int n,nt;
char s[N],t[N],s2[N][N];
int buc[255],b2[255];
int m;
char c[255];
bool beg[N],end[N];
int p[N];
bool f[N][N];
inline bool work(int k,int len){nt=len;for (int i=1;i<=nt;++i)t[i]=s[k+i-1];memset(f,0,sizeof f);for (int i=n;i>=1;--i){f[i][i]=(s[i]==t[1]);for (int j=i+1;j<=n;++j){f[i][j]|=(f[i][j-1]&&s[j]==t[(j-1-i+1)%nt+1]);for (int k=i+(j-i)%nt;k<j && !f[i][j];k+=nt)f[i][j]|=(f[i][k]&&f[k+1][j]);}}return f[1][n];
}
int main(){freopen("string.in","r",stdin);freopen("string.out","w",stdout);int T;scanf("%d",&T);while (T--){scanf("%s",s+1);n=strlen(s+1);memset(buc,0,sizeof buc);for (int i=1;i<=n;++i)buc[s[i]]++;m=0;for (char ch=' '+1;ch<='~';++ch)if (buc[ch])c[++m]=ch;int g=n;for (int i=1;i<=m;++i)g=gcd(g,buc[c[i]]);int l=1,r=n;while (l<n && s[l+1]!=s[1])++l;while (r>1 && s[r-1]!=s[n])--r;memset(beg,0,sizeof beg);memset(end,0,sizeof end);for (int i=1,j;i+l-1<=n;++i){for (j=1;j<=l;++j)if (s[i+j-1]!=s[j])break;if (j<=l)continue;beg[i]=1;}for (int i=n,j;i+r-n>=1;--i){for (j=n;j>=r;--j)if (s[i+j-n]!=s[j])break;if (j>=r)continue;end[i]=1;   }for (int len=max(l,n-r+1);len<=n;++len)if (n%len==0 && g%(n/len)==0){int t=n/len,hg=0;memset(b2,0,sizeof b2);for (int i=1;i<=len;++i)b2[s[i]]++;for (int i=1;i<=m;++i)if (b2[c[i]]*t==buc[c[i]])hg++;int i;for (i=1;i+len-1<=n;++i){if (beg[i] && end[i+len-1] && hg==m){if (work(i,len)){for (int j=i;j<i+len;++j)putchar(s[j]);putchar('\n');break;}}if (b2[s[i]]*t==buc[s[i]])hg--;b2[s[i]]--;if (b2[s[i]]*t==buc[s[i]])hg++;if (b2[s[i+len]]*t==buc[s[i+len]])hg--;b2[s[i+len]]++;if (b2[s[i+len]]*t==buc[s[i+len]])hg++;}if (i+len-1<=n)break;}}return 0;
}

总结

这都想不出来……我真是太菜了……

转载于:https://www.cnblogs.com/jz-597/p/11488881.html

[JZOJ6347] 【NOIP2019模拟2019.9.8】ZYB玩字符串相关推荐

  1. 6377. 【NOIP2019模拟2019.10.05】幽曲[埋骨于弘川]

    题目 题目大意 有个无限长的数列an{a_n}an​,a1=1a_1=1a1​=1,an=an−1+maxdightk(an−1)a_n=a_{n-1}+maxdight_k(a_{n-1})an​= ...

  2. 6360. 【NOIP2019模拟2019.9.18】最大菱形和(rhombus)

    Description Input Output Sample Input 5 5 2 0 1 5 7 3 -4 2 0 -9 8 3 9 0 7 8 2 -4 5 -7 1 4 5 8 7 0 6 ...

  3. 6374. 【NOIP2019模拟2019.10.04】结界[生与死的境界]

    题目 题目大意 给你一个数列,每次可以选择任意两个相邻的数xxx和yyy,将其删去,并在原来位置插入x+2yx+2yx+2y. 每次询问一个区间,对这个区间进行上述操作.求最后剩下的数最大是多少. 答 ...

  4. JZOJ6362. 【NOIP2019模拟2019.9.18】数星星(star)

    Description Solution 考虑分治,将每一个询问挂在包括它的最大的区间中. 只考虑中点往右的区间的贡献,那么每一个点对于覆盖它的最早的时间有一个贡献. 我们建一个虚树,并且用并查集路径 ...

  5. jzoj6384. 【NOIP2019模拟2019.10.23】珂学家

    Description Input Output 输出共 行,每行一个非负整数表示答案. Sample Input 2 1 1 2 3 2 1 3 5 Sample Output 4 只能选用试剂1 ...

  6. jzoj6377. 【NOIP2019模拟2019.10.05】幽曲[埋骨于弘川]

    题解 真的都快忘了. 首先,我们考虑排序,求出一个神奇的排列方式,也就是dfn序. 那么答案必定是在dfn序里面一些连续的段连接起来. 然后我们就判断这玩意儿是否满足在a里面出现过. 于是现在分两步走 ...

  7. JZOJ6384【NOIP2019模拟2019.10.23】珂学家

    珂学家 题目描述: 输入: 输出: 输出共mmm行,每行一个非负整数表示答案. 这道题看到是一个区间,便想到了数据结构之类的东西. 但是呢它好像不带修.所以初步判断这是个离线的题目. 再仔细观察发现, ...

  8. 模拟黑洞图像_解密真正的黑洞模样!终于不再是模拟照片,这次是玩真的!

    原标题:解密真正的黑洞模样!终于不再是模拟照片,这次是玩真的! 星协来自宇宙的礼物 2019年4月11日,科学家们召开了新闻发布会,向全球揭开了黑洞的神秘面纱!这张照片也是来之不易,全球汇集了200多 ...

  9. 抓球球的机器人应该怎么玩_闲鱼2019年应该怎么玩?闲鱼上面的几大规则

    闲鱼2019年应该怎么玩?闲鱼上面的几大规则 如今已经是2019年了,还是有好一些的伙伴们在求闲鱼流量,闲鱼新的一年是不是有什么大的改动,还可以照着往年的玩法继续做闲鱼吗,对于这样的问题,我实在有些看 ...

  10. 小心地放开玩字符串/字符数组(二)某类字符的个数

    /* * Copyright (c) 2012, 烟台大学计算机学院 * All rights reserved. * 文件名称:test.cpp * 作 者:徐凯旋 * 完成日期:2012 年 12 ...

最新文章

  1. python queue 调试_学Python不是盲目的,是有做过功课认真去了解的
  2. exchange 2010-诊断小工具简解
  3. 利用C#线程窗口调试多线程程序
  4. Cache占用过多内存导致Linux系统内存不足问题排查
  5. bulter机器人_科普!九款使用率最高的物流机器人大盘点!
  6. 汤姆克兰西全境封锁服务器维护时间,汤姆克兰西全境封锁无法登录怎么解决 无法登录解决方法攻略...
  7. linux常用命令速记
  8. [转载] python中日期和时间格式化输出的方法
  9. [转] VR-FORCES 介绍
  10. Kettle下载安装教程
  11. pdf转word文档保留原格式 本地离线软件
  12. Java的class是什么意思?
  13. 谷歌插件EpubPress 将网页保存为电子书
  14. matlab中ode的用法,关于matlab 的ode45用法
  15. 安卓手游脚本开发!闭关在家37天“吃透”这份345页PDF,已开源
  16. 京东物流一体化供应链建设实践
  17. 云计算概念及Linux系统详解
  18. 键盘录入 写入文件 quit时 结束
  19. Bugku流量分析题目总结
  20. Linux日常软件安装(FC6)

热门文章

  1. 浙工大计算机学院2013学年二等奖学金,关于2012—2013学年学院奖学金评定文件.doc...
  2. 暴雪在计算机名字,战网怎么改名字 战网改名字简单几步就能修改
  3. threejs的环境光+点光源+平行光源+球面光 以及hepler理解+阴影()
  4. Android 高级开发进阶图谱
  5. Mysql workbench画ER图
  6. android调用Camera.open方法报错“Too many cameras already open”
  7. ubuntu下查看软件安装信息
  8. Win10“混合现实门户”图标更新:加入Fluent Design风格
  9. 教师资格证面试缴费找不到服务器,2016年教师资格证考试报名网上缴费常见问题...
  10. 软件中的质量属性(二)