HDU-3746 Cyclic Nacklace

news/2024/7/10 4:11:43 标签: 算法, 优化, 数据结构

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3746


题目大意:

给你一个字符串,要求将字符串的全部字符最少循环2次需要添加的字符数。

例子:

abcabc 已经循环2次,添加数为0

abcac 没有循环2次,添加字符abcac。数目为5.

abcabcab 已经循环过2次,但第三次不完整,需要添加数为1


解题思路:

next[]数组的运用。

这里需要深刻理解next数组的含义,所以需要花费一定的功夫去弄懂这些。。

对于next数组,经过3天的学习,有了一定的认识。自己总结一下吧。

首先,求next数组有两种方法。第一种是严蔚敏教授那本数据结构上的求法。代码如下:

void getnext(const char *s)
{
	int i = 0, j = -1;
	nextval[0] = -1;
	while(i != len)
	{
		if(j == -1 || s[i] == s[j])
			nextval[++i] = ++j;
		else
			j = nextval[j];
	}
}

这种求法的含义是:

next[i]代表了前缀和后缀的最大匹配的值(需要彻底明白这点,相当重要)

另外一种是对这种算法的改进版本,代码如下:

void getnext(const char *p) //前缀函数(滑步函数)
{
	int i = 0, j = -1;
	nextval[0] = -1;
	while(i != len)
	{
		if(j == -1 || p[i] == p[j]) //(全部不相等从新匹配 || 相等继续下次匹配)
		{
			++i, ++j;
			if(p[i] != p[j]) //abcdabce
				nextval[i] = j;
			else //abcabca
				nextval[i] = nextval[j];
		}
		else
			j = nextval[j]; //子串移动到第nextval[j]个字符和主串相应字符比较
	}
}

改进的地方在于-1的运用,关于怎么优化我已经写过了。自己看下就行了。。。但是一定要明白。

不同之处:

没有优化的getnext函数,next数组存的是前缀和后缀的最大匹配值,而优化后的getnext函数存的是在这个基础,进行更高效的改进。

比如abcabca

改进前最后一个字符next[7]=4,表示的是前缀和后缀最大匹配是4,即abca和abca。

改进后的next[7]=-1。这点也需要彻底搞懂,才能灵活的运用next函数。

总结一下:

在求前缀和后缀的最大匹配值时,要使用第一种,也就是未优化算法。在运用KMP时,使用第二种算法,因为避免了多余的判断,更加高效。

YY:

其实我们可以发现KMP算法的精华部分是一个DP。每次右滑时,都是根据前面状态得到的有用信息进行的。相当于记忆化更新。这样算法才具有了很高的效率。

当然,理解这个算法确实需要仔细反复的研究,反正我是看了3天,才把这点基础东西搞的差不多,算是理解了80%吧。剩下的在以后做题的过程中慢慢发现吧。。。。


这道题的代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define N 100010

char s[N];
int nextval[N];
int len;

void getnext(const char *s)
{
	int i = 0, j = -1;
	nextval[0] = -1;
	while(i != len)
	{
		if(j == -1 || s[i] == s[j])
			nextval[++i] = ++j;
		else
			j = nextval[j];
	}
}

int main()
{
	int ncase;
	int length, add;
	scanf("%d", &ncase);
	while(ncase--)
	{
		scanf("%s", s);
		len = strlen(s);
		getnext(s);
		/*for(int i = 0; i <= len; ++i) //查看next数组的内容
			cout<<nextval[i]<<" ";
		cout<<endl;*/
		length = len - nextval[len]; //循环节的长度
		if(len != length && len % length == 0) //循环多次
			printf("0\n");
		else
		{
			add = length - nextval[len] % length; //取余的作用:abcab,去掉abc
			printf("%d\n",add);
		}
	}
	return 0;
}


http://www.niftyadmin.cn/n/1517027.html

相关文章

网站漏洞扫描软件wrbscanner_用于渗透测试的10种漏洞扫描工具

漏洞扫描工具是IT部门中必不可少的工具之一&#xff0c;因为漏洞每天都会出现&#xff0c;给企业带来安全隐患。漏洞扫描工具有助于检测安全漏洞、应用程序、操作系统、硬件和网络系统。黑客在不停的寻找漏洞&#xff0c;并且利用它们谋取利益。网络中的漏洞需要及时识别和修复…

使用 Elasticsearch

了解如何创建索引&#xff0c;添加&#xff0c;删除&#xff0c;更新文档 参考文档 开始使用 Elasticsearch 1 本文用到Elasticsearch和Kibana 可以看之前的两篇先安装好 Elasticsearch 安装 Kibana安装 Elasticsearch 里的接口都是通过 REST 接口来实现的。 GET 读取数…

Windows ce 桌面定制小结

Windows ce 桌面定制小结 一、采用standard shell, 去掉任务栏 代码%_winceroot%/public/shell/oak/hpc 我尝试了以下两种方法&#xff1a; 1、在taskbar.cpp中将函数BOOL CTaskBar::Register()的内容全部删除&#xff0c;直接return TRUE; 2、在explorer.cpp…

python 循环语句结果存储_实习之余的加餐:Python学习DAY 2--条件语句与循环语句

一、学习内容概括学习地址&#xff1a;阿里云登录 - 欢迎登录阿里云&#xff0c;安全稳定的云计算服务平台今天学习的主要内容有&#xff1a;条件语句if 语句if - else 语句if - elif - else 语句assert 关键词循环语句while 循环while - else 循环for 循环for - else 循环rang…

项目管理——Head First 软件开发

Doc 下载&#xff1a; https://download.csdn.net/download/qccz123456/10567658 时间&#xff1a;2018年3月22日星期四 作者&#xff1a;清村常争 一、伟大的软件开发——让客户满意 除开宏大的想法外&#xff0c;大多数项目都有两个焦点&#xff1a;要花多少钱&#xff1f;要…

缺氧游戏 不给计算机加水,缺氧中的物理学攻略 温度/装饰/水压/热导图文详解...

瓷砖——水压我们知道缺氧这个游戏有水啊气体啊&#xff0c;就会有水压 气压之类。气压不会压坏东西&#xff0c;但是水压就会压坏东西了。我们先来测定一下一格究竟可以承受多大的水压。通过图片可知&#xff0c;一格的水压极限是1100.然后我们把上面那个封住的瓷砖去掉像这个…

WinCE驱动开发问题精华集锦1

在mediaplayer全屏播放的时候&#xff0c;我可以用键盘上的某一个键调节声音大小&#xff0c;现在我想在屏幕上显示调节的结果就跟我们看电视一样能出来一些标记。当声音变大在屏幕上就增多&#xff0c;当声音变小的时候就减少 得到播放窗口的DC&#xff0c;然后在上面显示一个…

学计算机就是电子科技大学吗,电子科技大学和武汉大学计算机怎么选择?

先说出我心目中的答案&#xff0c;抉择电子科技大年夜学。常言到&#xff0c;术业有专攻。电子科技大年夜学专攻的就是电子、通信、打算机类的专业&#xff0c;并且电子科技大年夜学这类专业在工科院校中金榜落款&#xff0c;他的IT相干的专业敢与清华大年夜学媲美。武汉大年夜…