Plite
전자오락 공방
Plite
전체 방문자
오늘
어제
  • 분류 전체보기 (274)
    • 프로젝트 (18)
      • 완성 프로젝트 (3)
      • 프로젝트 진행 내역 (15)
    • 공부 및 정리 (241)
      • 백준 코드 (222)
      • C++ (8)
      • DirectX (2)
      • Unreal Engine (6)
      • 프로그래밍 패턴 (3)
    • 기타 (12)
      • 기타 주저리 (10)
    • 게임과 취미 (1)
    • 대문 (1)

블로그 메뉴

  • 홈
  • 프로젝트
  • 취미, 일상
  • 백준 프로필

공지사항

  • [Read Me]
  • 제 블로그에 방문하신 것을 환영합니다.

인기 글

태그

  • 세그먼트 트리
  • 위상 정렬
  • 구현
  • 조합론
  • 투포인터
  • 스택
  • 트리
  • 동적계획법
  • 최소 스패닝 트리
  • UC++
  • 누적합
  • 문자열
  • 이분탐색
  • 유니온 파인드
  • KMP
  • 기하
  • C++
  • 큐
  • 우선순위큐
  • SCC
  • 정수론
  • 분할정복
  • 브루트포스
  • 수학
  • 백준
  • 백트래킹
  • 트라이
  • 정렬
  • 그래프
  • LCA

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Plite

전자오락 공방

[C++]백준 - 4354번 문제
공부 및 정리/백준 코드

[C++]백준 - 4354번 문제

2021. 11. 18. 17:18

4354번: 문자열 제곱 (acmicpc.net)

 

4354번: 문자열 제곱

알파벳 소문자로 이루어진 두 문자열 a와 b가 주어졌을 때, a*b는 두 문자열을 이어붙이는 것을 뜻한다. 예를 들어, a="abc", b="def"일 때, a*b="abcdef"이다. 이러한 이어 붙이는 것을 곱셈으로 생각한다

www.acmicpc.net

 

4354번 : 문자열 제곱


알파벳 소문자로 이루어진 두 문자열 a와 b가 주어졌을 때, a*b는 두 문자열을 이어붙이는 것을 뜻한다. 예를 들어, a="abc", b="def"일 때, a*b="abcdef"이다.

이러한 이어 붙이는 것을 곱셈으로 생각한다면, 음이 아닌 정수의 제곱도 정의할 수 있다.

  • a^0 = "" (빈 문자열)
  • a^(n+1) = a*(a^n)

문자열 s가 주어졌을 때, 어떤 문자열 a에 대해서 s=a^n을 만족하는 가장 큰 n을 찾는 프로그램을 작성하시오.

 

입력


입력은 10개 이하의 테스트 케이스로 이루어져 있다. 각각의 테스트 케이스는 s를 포함한 한 줄로 이루어져 있다. s의 길이는 적어도 1이며, 백만글자를 넘지 않는다. 마지막 테스트 케이스의 다음 줄은 마침표이다.

 

 

출력


각각의 테스트 케이스에 대해, s=a^n을 만족하는 가장 큰 n을 찾은 뒤 출력한다.

 

 


 

생각해 볼 점


KMP 알고리즘 중 실패함수를 이용하는 문제입니다.

 

실패함수의 생성 원리를 생각해보면 문자열의 제곱 형태를 계산하기 용이합니다.

 

예시) ABABAB의 실패함수

Index 0 1 2 3 4 5
값 0 0 1 2 3 4

위 표와 같이 생성이 되었을 것입니다. 여기서

 

입력된 문자열 X = ABABAB

반복되는 문자열 Y = AB

제곱된 횟수 N = 3 

 

라고 정의하겠습니다.

 

X의 길이 - 마지막 Index의 값 = Y의 길이

 

(마지막 Index의 값 / Y의 길이) + 1 = 3

 

만약, 마지막 Index의 값이 Y의 길이로 나누어떨어지지 않는다면 그 문자열 X는 문자열 제곱의 형태가 아니므로

 

1을 출력하면 됩니다.

 

코드


#include <iostream>
using namespace std;
#pragma warning(disable : 4996)

int main()
{
	while (true)
	{
		char input[1000001];
		cin.getline(input, 1000001);
		
		//탈출 조건
		if (input[0] == '.' && input[1] == NULL) break;
		//공백을 받으면
		if (input[0] == NULL)
		{
			printf("0\n");
			continue;
		}

		int len = 0;
		for (; input[len] != NULL; len++) continue;
		int *Pi = new int[len];
		fill_n(Pi, len, 0);
		
		//Pi 배열 만들기
		for (int left = 0, right = 1; right < len; right++)
		{
			while (0 < left && input[left] != input[right]) left = Pi[left - 1];
			if (input[left] == input[right]) Pi[right] = ++left;
		}


		printf("%d\n", (len % (len - Pi[len - 1]) == 0 ? len / (len - Pi[len - 1]) : 1));
	}
	return 0;
}

 

그 외


 

저작자표시 (새창열림)

'공부 및 정리 > 백준 코드' 카테고리의 다른 글

[C++]백준 - 1305번 문제  (0) 2021.11.20
[C++]백준 - 6503번 문제  (0) 2021.11.18
[C++]백준 - 1786번 문제  (0) 2021.11.18
[C++]백준 - 2482번 문제  (0) 2021.11.17
[C++]백준 - 1032번 문제  (0) 2021.11.17
    '공부 및 정리/백준 코드' 카테고리의 다른 글
    • [C++]백준 - 1305번 문제
    • [C++]백준 - 6503번 문제
    • [C++]백준 - 1786번 문제
    • [C++]백준 - 2482번 문제
    Plite
    Plite
    개발 일지, 게임 이야기 등을 적어두는 공간입니다.

    티스토리툴바