校赛——1096Is The Same?(KMP或字符串的最小、大表示法)
1096: Is The Same?
Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 26 Solved: 8
[Submit][Status][Web Board]
Description
给出2个字符串S和T,如果可以通过循环移位使得S和T相等,则我们称S和T是同构字符串, 例如S=“abcd”, T=“bcda”,则S和T是同构字符串;而S=“abcd”和T=“bcad”则不是同构字符串。
循环移位是指:在⼀个长度为n的字符串S中,取⼀个任意下标i,把字符串分为两段,分别为 S1S2...Si 和Si+1Si+2...Sn,然后把字符串变为Si+1Si+2...SnS1S2...Si,例如S=“qwerty”,取i=3, 则变 为”rtyqwe”(注意,一个字符串本⾝身也算是它的同构字符串)。
Input
第⼀行包含一个整数T(1 <= T <= 20),代表测试组数。
对于每组数据,包含2个字符串,字符串长度都小于等于105且非空,输入保证字符串只包含小写字⺟。
Output
对于每组数据,如果这两个字符串是同构字符串,则输出Yes,否则输出No。
Sample Input
2
abcd
bcda
abcd
bcad
Sample Output
Yes
No
比赛的时候用的是据说效率差不多的strstr过的,毕竟题目只是要求输出是否匹配而不是查找出现位置。KMP比较长打起来费时间而且清空数组又要打一堆
代码:
#include<iostream> #include<algorithm> #include<cstdlib> #include<sstream> #include<cstring> #include<cstdio> #include<string> #include<deque> #include<stack> #include<cmath> #include<queue> #include<set> #include<map> using namespace std; typedef long long LL; #define INF 0x3f3f3f3f #define MM(a) memset(a,0,sizeof(a)) const int N=100010; char a[N],b[N],aa[2*N],bb[2*N]; int nexta[N],nextb[N]; inline void getnext(int ne[],char s[]) { int j=0,k=ne[0]=-1; int len=strlen(s); while (j<len) { if(k==-1||s[j]==s[k]) { j++; k++; ne[j]=k; } else k=ne[k]; } } inline bool kmp(int ne[],char s[],char p[]) { int i=0,j=0; int la=strlen(s),lb=strlen(p); while (i<la&&j<lb) { if(s[i]==p[j]||j==-1) { i++; j++; } else j=ne[j]; } if(j==lb) return true; else return false; } int main(void) { int tcase,i,j; scanf("%d",&tcase); while (tcase--) { MM(a); MM(b); MM(aa); MM(bb); MM(nexta); MM(nextb); scanf("%s%s",a,b); if(strlen(a)!=strlen(b)) { puts("No"); continue; } strcat(aa,a); strcat(aa,a); strcat(bb,b); strcat(bb,b); getnext(nexta,a); getnext(nextb,b); if(kmp(nexta,bb,a)||kmp(nextb,aa,b)) puts("Yes"); else puts("No"); } return 0; }
最小表示法代码:
#include<iostream> #include<algorithm> #include<cstdlib> #include<sstream> #include<cstring> #include<cstdio> #include<string> #include<deque> #include<stack> #include<cmath> #include<queue> #include<set> #include<map> using namespace std; typedef long long LL; #define INF 0x3f3f3f3f inline string minP(string s) { int i=0,j=1,k=0,l=s.size(); while (i<l&&j<l&&k<l) { int t=s[(i+k)%l]-s[(j+k)%l]; if(!k) k++; else { if(t>0) j+=k+1; else i+=k+1; k=0; if(i==j) j++; } } s=s+s; return s.substr(min(i,j),l); } int main(void) { int tcase; string a,b; cin>>tcase; while (tcase--) { cin>>a>>b; a=minP(a); b=minP(b); if(a==b) cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }