[USACO 2014 Feb Silver]scode

14 篇文章 0 订阅
1 篇文章 0 订阅

[题目描述]

XYW和他的男人聊天的时候,不让DZY看见他们聊天内容,他们决定用以下方式给一个字符串加密:每次把这个字符串的一个非空前缀或者后缀(不能是这个字符串的本身)加到这个字符串的前面或者后面。比如ABC就可以加密成 AABC ABABC BCABC CABC ABCA ABCAB ABCBC ABCC。

现在DZY拿到一个字符串(长度至多100),已知这个字符串从一个长度最少为2的字符串经过了至少一次加密(可以多次),现在DZY想要知道有多少种加密方案可以加密得到当前的字符串(初始字符串不同或者操作序列不同都视为不同的方案,结合样例解释食用更佳)。请你输出方案数对2014取模的值。


就是记忆化搜索,判断的时候哈希一下嘛。。真·水题

觉得自己那个ever,forever名字取得挺好的,以后数据结构都这么写了233。。

const shuru='scode.in';
	  shuchu='scode.out';
	  modn=1000007;
	  seed=131;
type point=^node;
	 node=record
		data:longint;
		pppp:string;
		next:point;
		  end;
var	hash:array[0..modn] of point;
	s:string;
	i,j,k,n,step:longint;
	p:point;
procedure init;
begin
	readln(s);
end;
function gothash(s:string):int64;
var i:longint;
begin
  gothash:=0;
  for i:=1 to length(s) do
    gothash:=(gothash*seed+ord(s[i]))and $FFFFFFF;
 gothash:=gothash mod modn;
end;
function ever(s:string):boolean;
var x:longint;
begin
	x:=gothash(s);
	p:=hash[x];
	while p<>nil do
	begin
		if p^.pppp=s then begin
							step:=p^.data;
							exit(true);
						  end;
		p:=p^.next;
	end;
	exit(false);
end;
procedure forever(s:string;a:longint);
var x:longint;
begin
	x:=gothash(s);
	new(p);
	p^.pppp:=s;
	p^.data:=a;
	p^.next:=hash[x];
	hash[x]:=p;
end;
function search(s:string;sign:longint):longint;
var len,i,changshu,tot:longint;
	str:string;
begin
	search:=sign;
	if length(s)<2 then exit(0);
	if length(s)=2 then exit(1);
	if ever(s) then exit(step);
	len:=length(s);
	if len and 1=0 then changshu:=len shr 1-1
				   else changshu:=len shr 1;
	for i:=1 to changshu do
		if copy(s,1,i)=copy(s,i+1,i) then begin
											str:=s;
											delete(str,1,i);
											search:=(search+search(str,1)) mod 2014;
										  end;
	for i:=1 to changshu do
		if copy(s,1,i)=copy(s,len-i+1,i) then begin
												str:=s;
												delete(str,1,i);
												search:=(search+search(str,1)) mod 2014;
											  end;
	for i:=1 to changshu do
		if copy(s,1,i)=copy(s,len-i+1,i) then begin
												str:=s;
												delete(str,len-i+1,i);
												search:=(search+search(str,1)) mod 2014;
											  end;
	for i:=1 to changshu do
		if copy(s,len-i-i+1,i)=copy(s,len-i+1,i) then begin
														str:=s;
														delete(str,len-i+1,i);
														search:=(search+search(str,1)) mod 2014;
													  end;
	forever(s,search);
end;
procedure main;
begin
	init;
	writeln(search(s,0));
end;
begin
	main;
end.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值