#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;}
template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;}
const int N=1e6+10,M=0,Z=1e9+7,ms63=0x3f3f3f3f;
int casenum,casei;
int n;
char a[N],b[N];
int nxt[N];
void init()
{
for(int i=1;i<=n;++i)
{
if(b[i]=='N')b[i]='S';
else if(b[i]=='S')b[i]='N';
else if(b[i]=='W')b[i]='E';
else if(b[i]=='E')b[i]='W';
}
for(int i=1;i<=n/2;++i)swap(b[i],b[n+1-i]);
}
void getnxt()
{
int j=0;nxt[1]=0;
for(int i=2;i<=n;++i)
{
while(j&&b[j+1]!=b[i])j=nxt[j];
if(b[j+1]==b[i])++j;
nxt[i]=j;
}
}
void kmp()
{
int j=0;
for(int i=1;i<=n;++i)
{
while(j&&b[j+1]!=a[i])j=nxt[j];
if(b[j+1]==a[i])++j;
}
puts(j?"NO":"YES");
}
int main()
{
while(~scanf("%d",&n))
{
--n;scanf("%s%s",a+1,b+1);
init();
getnxt();
kmp();
}
return 0;
}
/*
【trick&&吐槽】
这题题意好难懂!
【题意】
给你两条长度同为n(2<=n<=1e6)的路径。
每条路径有行走规则,显然,在路径上的行走步数就会是n-1。
我们会接受到一个指令(这个指令由你给出)。
对于任意一条路径而言,一共有n个位置——
如果我们此刻是位于第i个位置,现在接受的这条指令的移动方向是dir,
而且如果路径上第i-1或者i+1位置(首先这个位置需要是存在的),是可以通过这个dir到达的,那么我们就会执行这条指令。
现在问你,是否存在一个指令,可以使得两条路径在指令结束的时候,都恰好达到最后的位置。
存在输出YES,不存在输出NO。
【类型】
脑洞 KMP
【分析】
这道题不光题意难懂,
懂了之后也感觉很鬼畜,而不知道怎么做。
然而这题,却是有结论的。
对于操作序列a,我们保持不变。
对于操作序列b,我们把所有的方向反过来,再把这个串的前后做对称颠倒操作。我们称这个操作为reverse操作,对应的串被叫做reverse串。
为什么我们想到reverse串呢?
因为这道题有一个很奇怪的限制,就是我们从一个位置,接受指令,可以走这个位置在定位上的前一个位置或者后一个位置。
也就是说,行走操作,对于一个串和其翻转串,是存在着对称性的。
基于之前找出的所有性质,我们可以从一些小数据模拟中找出问题的答案——
数据1:
2
S
N
对于这组数据,我们发现答案一定是NO。
因为,两个路径上的最后一步运动是反向的。
一个位点向下走了,对于另外一个位点,就会向上走。永远不会有两个位点同时走到终点的时刻。
其实问题可以扩大化,数据可以变成——
len
x...xS
x...xN
只是最后一步是恰好是反向的。同理,一样不可能使得两条路径同时到达终点。
那么,难道就是——
如果最后一步是恰好反向,那答案就是NO;否则答案就是YES?
不!
数据2:
...NW
...ES
最后一步并非反向,但是,最后两步是恰好对称反向。
也就是说,最后两步是形成恰好的反结构。我们发现答案也是NO。
我们由此延伸出一个判定。
如果a和b两个序列,可以从a中取出一个后缀,而在b中有同样长度的后缀,是恰好对称反向的,那么答案就是NO
为什么呢?
我们可以形成一个想象,拿出这两个路径最后反向对称的部分
把它们放在上下层,使它们在结构上形成覆盖关系。
于是,我们发现,如果两个序列都达到最后一个位置,必要条件是,两个路径序列需要形成交错。
首先,对于相邻位点(pos a pos b),显然因为所需指令不同,所以我们是不可能同时从pos a 到pos b,并从pos b 到pos a的。
那么,如果形成交错,我们一定要在这两个正反路径上,先到达一个相同的点。
肯定的是,这个相同的点,不会同时是两个路径的终点。
在这个时候,不论接下来的操作序列是什么,在两条路径上行走,都会存在同进同退的行走方案。
因而,我们不可能在这两个路径最后反向对称的部分,同时到达两个末端位置。于是,NO的结果是显然而且确定的。
====================================
于是,我们就可以说,这道题目输出NO的条件是——
当且仅当,在a串中存在某个后缀,与b串的翻转串中同长度后缀恰好匹配 吗?
如何证明呢?证明就要有证明充要性,即证明其充分性和必要性。
充分性我们已经证明了,即存在这样的对称结构,那么答案就是NO。
然而,我们还需要再考虑其必要性——
即证明,不存在反向对称后缀结构的话,对于两个路径的答案一定是YES么?
有一种走法。
我们先在路径1,通过最少步数走到末节点,然后如果路径2,没有走到末节点的话,
我们再在路径2,通过最少步数走到末节点。
以此循环,那么最后一定可以使得两个点都走到末点。
为什么呢?
因为我们在两条路径上,都有一个到末点的距离。分别设为disa和disb,总距离设为dis。
那么,我们可以说,按照前述的方案操作的话,总的dis一定是严格减少的。
为什么呢?
比如说我们现在a路径到末点了,b路径开始向其末点走,那么dis不减少的条件,显然是a路径与b路径最后部分恰好对称反向。
而这个结构已经证明不存在了,于是总的dis一定严格减少,答案一定是YES.
==================
于是这道题就做完啦.
我们可以通过
反向一个串,然后再把它做对称,得到的串作为模板串。
然后另外一个串做匹配串,做KMP。
如果不变换的那个串,最后一个位置是存在匹配长度的。
那么意思是,存在反向对称结构(为什么?可以围绕KMP体会一下)。答案就是NO
而最后一个位置的匹配长度是0的话,答案就是YES
==================
于是这道题就完全做完啦~
【时间复杂度&&优化】
O(n)
*/
【Codeforces Round 336 (Div 2) E】【KMP 构造 脑洞 好题 模拟找规律】Marbles 两条路径同时出发前后行走能否恰好同时到终点
最新推荐文章于 2018-05-31 19:47:22 发布