列表

详情


NC50314. Seek the Name, Seek the Fame

描述

给定若干字符串(这些字符串总长),在每个字符串中求出所有既是前缀又是后缀的子串长度。
例如:ababcababababcabab,既是前缀又是后缀的:ab,abab,ababcabab,ababcababababcabab。

输入描述

输入若干行,每行一个字符串。

输出描述

对于每个字符串,输出一行,包含若干个递增的整数,表示所有既是前缀又是后缀的子串长度。

示例1

输入:

ababcababababcabab
aaaaa

输出:

2 4 9 18
1 2 3 4 5

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 100ms, 内存消耗: 6608K, 提交时间: 2019-11-17 19:59:17

#include<bits/stdc++.h>
using namespace std;

int main() {
  string s;
  while (cin >> s) {
    vector<unsigned> H(s.size() + 1);
    vector<unsigned> B(s.size() + 1);
    for (int i = 0; i < s.size(); i++) H[i+1] = H[i]*33+s[i];
    B[0] = 1;
    for (int i = 0; i < s.size(); i++) B[i+1] = B[i]*33;
    for (int i = 1; i <= s.size(); i++) {
      if (H[s.size() - i]*B[i] + H[i] == H.back()) {
        cout << i << " ";
      }
    }
    cout << endl;
  }
}

C++(g++ 7.5.0) 解法, 执行用时: 53ms, 内存消耗: 14508K, 提交时间: 2022-08-23 11:00:45

//the code is from chenjh
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long LL;
char s[2000005];
const LL p=13337;
LL k[10000001],hs[10000001];
int main() {
	k[0]=1;
	for(int i=1;i<=1000001;i++)k[i]=k[i-1]*p;
	while(~scanf("%s",s+1)) {
		int l=strlen(s+1);
		hs[0]=0;
		for(int i=1;i<=l;i++)
			hs[i]=hs[i-1]*p+(LL)s[i];
		for(int i=1;i<=l;i++)
			if(hs[i]==hs[l]-hs[l-i]*k[i])
				printf("%d ",i);
		putchar('\n');
	}
}

C++11(clang++ 3.9) 解法, 执行用时: 79ms, 内存消耗: 6792K, 提交时间: 2020-03-05 12:51:19

#include<bits/stdc++.h>
using namespace std;
int main()
{
	string s;
	while(cin>>s)
	{
		vector<unsigned> H(s.size()+1);
		vector<unsigned> B(s.size()+1);
		for(int i=0;i<s.size();i++) H[i+1]=H[i]*33+s[i];
		B[0]=1;
		for(int i=0;i<s.size();i++) B[i+1]=B[i]*33;
		for(int i=1;i<=s.size();i++)
		{
			if(H[s.size()-i]*B[i]+H[i]==H.back())
			{
				cout<<i<<" ";
			}
		}
		cout<<endl;
		
	}
}

上一题