cf727e
题意:给你一个模式串和一堆长度相同的不相同的匹配串,问是否有一个方案可以让这个模式串由这些匹配串首尾相连组成,每个串只能出现一次.
思路:还是比较简单的,显然模式串每个位置最多匹配一个匹配串,因为所有的匹配串严格不同,每个位置有没有匹配哪个匹配串用ac自动机很容易就能跑出来,然后枚举一下位置就ok,还有模式串应该在开头加上尾部的一些字符,因为要求的是这个模式串要看成一个环.
#include <bits/stdc++.h>
using namespace std;
char aim[];
int pos[];
char temp[];
int total;
struct Root
{
Root *next[];
int count;
Root *fail;
Root()
{
for(int i=; i<; i++)
next[i]=NULL;
fail=NULL;
count=;
}
};
queue<Root *>q;
class AC_auto
{
public:
AC_auto();
void insert(char object[],int num);
void ac_auto();
void match(char aim[]);
private:
Root *root;
};
AC_auto::AC_auto()
{
root=new Root();
}
void AC_auto::insert(char object[],int num)
{
int len=strlen(object);
Root *temp=root;
for(int i=; i<len; i++)
{
if(temp->next[object[i]-'a']==NULL)
{
Root *temp1=new Root();
temp->next[object[i]-'a']=temp1;
}
temp=temp->next[object[i]-'a'];
}
temp->count=num;
}
void AC_auto::ac_auto()
{
while(!q.empty())q.pop();
q.push(root);
Root *temp1,*temp2;
while(!q.empty())
{
temp1=q.front();
q.pop();
for(int i=; i<; i++)
{
if(temp1->next[i])
{
if(temp1==root)
temp1->next[i]->fail=root;
else
{
temp2=temp1->fail;
while(temp2)
{
if(temp2->next[i])
{
temp1->next[i]->fail=temp2->next[i];
break;
}
temp2=temp2->fail;
}
if(temp2==NULL)
temp1->next[i]->fail=root;
}
q.push(temp1->next[i]);
}
}
}
}
void AC_auto::match(char aims[])
{
int len=strlen(aims);
Root *temp1,*temp=root;
for(int i=; i<len; i++)
{
if(aims[i]>'z'||aims[i]<'a')
{
temp=root;
continue;
}
while(temp->next[aims[i]-'a']==NULL&&temp!=root)
temp=temp->fail;
temp=temp->next[aims[i]-'a'];
if(!temp)temp=root;
if(temp->count)
pos[i]=temp->count;
}
}
bool sign[];
int main()
{
int n,k;
scanf("%d%d",&n,&k);
scanf("%s",aim+k);
for(int i=;i<k;i++)
aim[i]=aim[(n+)*k-k+i];
AC_auto *ac_auto=new AC_auto();
int g;
scanf("%d",&g);
for(int i=;i<=g;i++)
{
scanf("%s",temp);
ac_auto->insert(temp,i);
}
ac_auto->ac_auto();
ac_auto->match(aim);
for(int i=k;i<*k;i++)
{
for(int j=i;j<n*k+k;j+=k)
{
if(pos[j]==)
break;
else if(sign[pos[j]])
break;
sign[pos[j]]=true;
if(j+k>=n*k+k)
{
printf("YES\n");
for(int j=i;j<n*k+k;j+=k)
printf("%d ",pos[j]);
return ;
}
}
for(int j=i;j<n*k+k;j+=k)
{
if(pos[j]==)
break;
sign[pos[j]]=false;
}
}
printf("NO\n");
return ;
}
cf727e的更多相关文章
- 【CodeForces727E/CF727E】Games on a CD (字符串哈希)
题目: CodeForces727E 分析: 看到字符串比较,肯定想到哈希啊--现学的哈希,先丢两个重要的公式 (\(seed\)是大于字符集大小的质数,\(p\)是大质数) \[hash[i]=(h ...
随机推荐
- 百度地图API地理位置和坐标转换
1.由地名(省份.城市.街道等)得到其对应的百度地图坐标: http://api.map.baidu.com/geocoder/v2/?output=json&ak=你从百度申请到的Key&a ...
- Python基础语法(二)
类中的方法定义前如果有 @staticmethod 则此方法通过类名调用,如:dict.fromkeys() : 如果没有,则此方法通过对象调用 三元运算 name=值1 if 条件 else 值2 ...
- PSP(11.16~11.23)
18号 类别c 内容c 开始时间s 结束e 中断I 净时间T 看书 构建之法 9:00 10:00 0 60m 看书 查资料 10:00 11:15 5 70m 个人 写博客 13:30 14:55 ...
- 数据结构与算法(1)支线任务3——Largest Rectangle in Histogram
题目如下:(https://leetcode.com/problems/largest-rectangle-in-histogram/) Given n non-negative integers r ...
- (转载)FT232RL通信中断问题解决办法总结
原文地址:http://cuiweidabing.blog.163.com/blog/static/66631928201101514021658/ FT232RL是FTDI(www.ftdichip ...
- android 绑定spinner键值对显示内存地址的问题
初学android,估计是.net学傻了,觉得android好麻烦. 绑定下拉菜单Spinner键值对. 参照这篇文章,地址:http://blog.csdn.net/shouliang52000/a ...
- SQL Server获取月度列表
-- 获取月度列表 if exists(select 1 from sysobjects where name = 'proc_GetDateMonthList' and type = 'p') dr ...
- c#与js中10进制16进制的转化,记录防忘
js: var param="11"; param=parseInt(param,16); //17 param=parseInt(param,10); //11 //后面的参 ...
- MSSQL PIVOT 实现行列转置
create table #temp ( ProdStep varchar(40), ModuleStatus varchar(40), Cnt int ); insert into #temp va ...
- 【ios 7】 之后的设置系统的状态栏隐藏的方法分享
由于在做视频播放的的项目,一直困扰的是,视频全屏幕播放的时候,系统的状态栏会隐藏不掉,虽然可以设置为透明的状态来显示,但是电池的状态一直隐藏不掉,查看网上的说法也就是说,要么来控制,他的hidden ...