[이 질문은 문자열의 런 을 계산 하기위한 후속 조치입니다 ]
마침표
p
문자열은w
임의의 양의 정수이다p
되도록w[i]=w[i+p]
이 방정식의 양쪽이 정의 될 때마다. 하자per(w)
의 작은 기간의 크기를 나타낸다w
. 우리는 문자열w
이주기적인 iff 라고 말합니다per(w) <= |w|/2
.
따라서 비공식적으로주기적인 문자열은 다른 문자열에서 적어도 한 번 반복 된 문자열입니다. 유일한 합병증은 문자열의 끝에 적어도 한 번 전체가 반복되는 한 반복되는 문자열의 전체 사본이 필요하지 않다는 것입니다.
예를 들어 string을 고려하십시오 x = abcab
. per(abcab) = 3
로 x[1] = x[1+3] = a
, x[2]=x[2+3] = b
더 작은 기간이 없습니다. 따라서 문자열 abcab
은 주기적이 아닙니다. 그러나 문자열 ababa
은로 주기적 per(ababa) = 2
입니다.
이상의 예로서, abcabca
, ababababa
및는 abcabcabc
또한 주기적이다.
정규 표현식을 좋아하는 사람들에게는 문자열이 주기적인지 아닌지를 감지합니다.
\b(\w*)(\w+\1)\2+\b
이 작업은 더 긴 문자열에서 모든 최대 주기 하위 문자열 을 찾는 것 입니다. 이들은 때때로 문헌에서 런 이라고 불린다 .
하위 문자열은
w
이주기와도 인 경우 최대주기적인 문자열 (실행)이다w[i-1] = w[i-1+p]
아니다w[j+1] = w[j+1-p]
. 공식적으로 "실행"은 같은 기간의 더 큰 "실행"에 포함될 수 없습니다.
두 개의 런은 전체 문자열의 다른 위치에서 발생하는 동일한 문자열을 나타낼 수 있기 때문에 간격으로 런을 나타냅니다. 위의 정의는 간격으로 반복됩니다.
문자열에서 실행 (또는 최대주기 스트링)의
T
간격이다[i...j]
으로j>=i
되도록,
T[i...j]
마침표가있는 주기적 단어입니다.p = per(T[i...j])
- 최대입니다. 공식적으로도
T[i-1] = T[i-1+p]
아니다T[j+1] = T[j+1-p]
. 비공식적으로, 실행은 같은 기간의 더 큰 실행에 포함될 수 없습니다.
넣어야하는 RUNS(T)
문자열의 실행의 설정 T
.
달리기의 예
문자열의 사 개 최대주기적인 문자열 (실행)이
T = atattatt
있다T[4,5] = tt
,T[7,8] = tt
,T[1,4] = atat
,T[2,8] = tattatt
.문자열은
T = aabaabaaaacaacac
다음과 같은 7 개 최대주기적인 문자열 (실행)를 포함T[1,2] = aa
,T[4,5] = aa
,T[7,10] = aaaa
,T[12,13] = aa
,T[13,16] = acac
,T[1,8] = aabaabaa
,T[9,15] = aacaaca
.문자열
T = atatbatatb
에는 다음 세 가지 런이 포함됩니다. 그들은 :T[1, 4] = atat
,T[6, 9] = atat
및T[1, 10] = atatbatatb
.
여기서는 1 인덱싱을 사용하고 있습니다.
작업
2에서 시작하는 각 정수 n에 대해 length의 이진 문자열에 포함 된 최대 개수의 런을 출력하도록 코드를 작성하십시오 n
.
점수
귀하의 점수는 n
120 초 만에 도달 하는 최고 점수이므로 모든 k <= n
사람에 대해 귀하보다 더 높은 정답을 게시 한 사람은 없습니다. 당신은 모든 최적의 답변을 가지고 있다면 분명히 당신은 n
당신이 게시 한 최고 점수를 얻을 것이다 . 그러나 귀하의 답변이 최적이 아니더라도 다른 사람이 이길 수 없다면 여전히 점수를 얻을 수 있습니다.
언어와 라이브러리
원하는 언어와 라이브러리를 사용할 수 있습니다. 가능한 경우 코드를 실행할 수 있으면 좋을 것이므로 가능한 경우 Linux에서 코드를 실행 / 컴파일하는 방법에 대한 자세한 설명을 포함하십시오.
옵티마 예제
다음에서 : n, optimum number of runs, example string
.
2 1 00
3 1 000
4 2 0011
5 2 00011
6 3 001001
7 4 0010011
8 5 00110011
9 5 000110011
10 6 0010011001
11 7 00100110011
12 8 001001100100
13 8 0001001100100
14 10 00100110010011
15 10 000100110010011
16 11 0010011001001100
17 12 00100101101001011
18 13 001001100100110011
19 14 0010011001001100100
20 15 00101001011010010100
21 15 000101001011010010100
22 16 0010010100101101001011
내 코드는 정확히 무엇을 출력해야합니까?
각 n
코드 마다 단일 문자열과 그에 포함 된 실행 횟수가 출력되어야합니다.
내 컴퓨터 타이밍이 내 컴퓨터에서 실행됩니다. 이것은 AMD FX-8350 8 코어 프로세서에 표준 우분투 설치입니다. 이것은 또한 코드를 실행할 수 있어야 함을 의미합니다.
선행 답변
- C의 Anders Kaseorg에 의한 49 . 단일 스레드 및 L = 12 (2GB RAM)로 실행됩니다.
- C의 cdlane에 의한 27 .
{0,1}
-strings 만을 고려하기를 원한다면, 명시 적으로 언급하십시오. 그렇지 않으면 알파벳이 무한대 일 수 있으며 테스트 케이스가 최적의 이유를 알 수 없습니다 {0,1}
. 문자열 만 검색 한 것 같습니다 .
n
까지 12
그리고 바이너리 알파벳을 이길 수 없다. 경험적으로 나는 더 많은 문자를 추가하면 실행의 최소 길이가 증가하기 때문에 이진 문자열이 최적이어야한다고 기대합니다.