[JZOJ6347] 【NOIP2019模拟2019.9.8】ZYB玩字符串
题目
题目大意
有一个字符串\(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玩字符串相关推荐
- 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= ...
- 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 ...
- 6374. 【NOIP2019模拟2019.10.04】结界[生与死的境界]
题目 题目大意 给你一个数列,每次可以选择任意两个相邻的数xxx和yyy,将其删去,并在原来位置插入x+2yx+2yx+2y. 每次询问一个区间,对这个区间进行上述操作.求最后剩下的数最大是多少. 答 ...
- JZOJ6362. 【NOIP2019模拟2019.9.18】数星星(star)
Description Solution 考虑分治,将每一个询问挂在包括它的最大的区间中. 只考虑中点往右的区间的贡献,那么每一个点对于覆盖它的最早的时间有一个贡献. 我们建一个虚树,并且用并查集路径 ...
- jzoj6384. 【NOIP2019模拟2019.10.23】珂学家
Description Input Output 输出共 行,每行一个非负整数表示答案. Sample Input 2 1 1 2 3 2 1 3 5 Sample Output 4 只能选用试剂1 ...
- jzoj6377. 【NOIP2019模拟2019.10.05】幽曲[埋骨于弘川]
题解 真的都快忘了. 首先,我们考虑排序,求出一个神奇的排列方式,也就是dfn序. 那么答案必定是在dfn序里面一些连续的段连接起来. 然后我们就判断这玩意儿是否满足在a里面出现过. 于是现在分两步走 ...
- JZOJ6384【NOIP2019模拟2019.10.23】珂学家
珂学家 题目描述: 输入: 输出: 输出共mmm行,每行一个非负整数表示答案. 这道题看到是一个区间,便想到了数据结构之类的东西. 但是呢它好像不带修.所以初步判断这是个离线的题目. 再仔细观察发现, ...
- 模拟黑洞图像_解密真正的黑洞模样!终于不再是模拟照片,这次是玩真的!
原标题:解密真正的黑洞模样!终于不再是模拟照片,这次是玩真的! 星协来自宇宙的礼物 2019年4月11日,科学家们召开了新闻发布会,向全球揭开了黑洞的神秘面纱!这张照片也是来之不易,全球汇集了200多 ...
- 抓球球的机器人应该怎么玩_闲鱼2019年应该怎么玩?闲鱼上面的几大规则
闲鱼2019年应该怎么玩?闲鱼上面的几大规则 如今已经是2019年了,还是有好一些的伙伴们在求闲鱼流量,闲鱼新的一年是不是有什么大的改动,还可以照着往年的玩法继续做闲鱼吗,对于这样的问题,我实在有些看 ...
- 小心地放开玩字符串/字符数组(二)某类字符的个数
/* * Copyright (c) 2012, 烟台大学计算机学院 * All rights reserved. * 文件名称:test.cpp * 作 者:徐凯旋 * 完成日期:2012 年 12 ...
最新文章
- python queue 调试_学Python不是盲目的,是有做过功课认真去了解的
- exchange 2010-诊断小工具简解
- 利用C#线程窗口调试多线程程序
- Cache占用过多内存导致Linux系统内存不足问题排查
- bulter机器人_科普!九款使用率最高的物流机器人大盘点!
- 汤姆克兰西全境封锁服务器维护时间,汤姆克兰西全境封锁无法登录怎么解决 无法登录解决方法攻略...
- linux常用命令速记
- [转载] python中日期和时间格式化输出的方法
- [转] VR-FORCES 介绍
- Kettle下载安装教程
- pdf转word文档保留原格式 本地离线软件
- Java的class是什么意思?
- 谷歌插件EpubPress 将网页保存为电子书
- matlab中ode的用法,关于matlab 的ode45用法
- 安卓手游脚本开发!闭关在家37天“吃透”这份345页PDF,已开源
- 京东物流一体化供应链建设实践
- 云计算概念及Linux系统详解
- 键盘录入 写入文件 quit时 结束
- Bugku流量分析题目总结
- Linux日常软件安装(FC6)
热门文章
- 浙工大计算机学院2013学年二等奖学金,关于2012—2013学年学院奖学金评定文件.doc...
- 暴雪在计算机名字,战网怎么改名字 战网改名字简单几步就能修改
- threejs的环境光+点光源+平行光源+球面光 以及hepler理解+阴影()
- Android 高级开发进阶图谱
- Mysql workbench画ER图
- android调用Camera.open方法报错“Too many cameras already open”
- ubuntu下查看软件安装信息
- Win10“混合现实门户”图标更新:加入Fluent Design风格
- 教师资格证面试缴费找不到服务器,2016年教师资格证考试报名网上缴费常见问题...
- 软件中的质量属性(二)