팬미팅 (난이도 - 상)

2022. 9. 14. 20:26·알고리즘 (with JAVA)/분할 정복 알고리즘

1. 문제 설명

(1) 팬미팅에 참가한 M명의 팬들은 줄을 서서 맨 오른쪽 멤버에서부터 시작해 한 명씩 왼쪽으로 움직이며 포옹합니다.

 

(2) 아래의 그림은 행사 과정 일부를 보여줍니다. a~c는 세 명의 하이퍼시니어 멤버이고, 0~4는 다섯 명의 팬들입니다.

(1) 실행 과정

 

(3) 하지만 하이퍼시니의 남성 멤버들이 남성 팬과 포옹하기가 민망하다고 여겨서, 남성 팬과는 포옹 대신 악수를 합니다.

 

(4) 줄을 선 멤버들과 팬들의 성별이 각각 주어질 때 팬미팅이 진행되는 과정에서 하이퍼시니어의 모든 멤버가 동시에 포옹

하는 일이 몇 번이나 있는지 계산하는 프로그램을 만드시오.

 

 

 

 

2. 입출력 조건 및 예제

입력 조건

(1) 멤버들의 성별과 팬들의 성별을 각각 나타내는 두 줄의 문자열로 구성한다.

(2) M은 남자, F는 여자를 의미한다.

(3) 맴버의 수와 팬들의 수는 모두 1이상 200,000 이하의 정수이며, 멤버의 수는 항상 팬의 수 이하이다.

 

출력 조건

(1) 멤버들이 동시에 포옹하는 일이 몇 번이나 있는지 출력하시오.

 

 

입력 예제

4

FFFMMM

MMMFFF

FFFFF

FFFFFFFFFF

FFFFM

FFFFFMMMMF

MFMFMFFFMMMFMF

MMFFFFFMFFFMFFFFFFMFFFMFFFFMFMMFFFFFFF

 

출력 예제

1

6

2

2

 

 

 

 

3. 제약 조건

(1) 프로그램은 10초 안에 실행되어야 하며, 64MB 이하의 메모리를 사용해야 한다.

 

 

 

 

4. 가정법

X

 

 

 

 

5. 기저 사례

X

 

 

 

 

6. 코드

: 두 가지 코드가 존재한다.

 

먼저, (1)의 코드처럼 무식하게 접근하는 것이다. 모든 시뮬레이션을 한 번씩 실행시켜 Brute_Force를 수행한다.

 

그러나, (1)의 시간 복잡도는 대략 O(MN-M^2)이 나오게 된다. 그렇게 되면 N과 M이 각각 20만에 달하는 숫자가 나오면 

시간 안에 풀기 어렵다는 것을 알게된다.

 

그래서 우리는 다른 방법으로 두 큰 수를 구하는 알고리즘 즉, 카라츠바 방법을 사용해 보는 것이다. 아래의 그림을 보자.

 

기본적인 카라츠바 계산 공식이다. 이것을 이용할려면 계산 값을 가지고 남성은 1, 여성은 0으로 변환하여 사용한다.

 

그러나, 이것보다 더 간단하게 &연산을 이용하는 방법이 있는데, (2)의 코드를 보고 이해하자.

 

 

(1) Brute Force

public class FanMeeting1 {
    private static BufferedReader sc = new BufferedReader(new InputStreamReader(System.in));
    private static StringBuilder builder = new StringBuilder();

    private static String M, N;

    public static void main(String[] args) throws Exception{
        int c = Integer.parseInt(sc.readLine());

        for(int i=0; i<c; i++) {
            M = sc.readLine();
            N = sc.readLine();
            builder.append(bruteForce()+"\n");
        }

        System.out.println("\n"+builder);
    }

    private static int bruteForce() {
        int ret = 0;

        for(int i=0; i<N.length() - M.length()+1; i++) {

            // 만약 남성과 남성끼리 만남이 있으면 바로 break와
            // 남성과 남성끼리의 만남이 없으면 바로 ret++를 한다.
            boolean isOk = false;

            for(int j=0; j<M.length(); j++) {
                if((M.charAt(j) == 'M' && N.charAt(j+i) == 'M')) {
                    isOk = false;
                    break;
                }
                isOk = true;
            }
            if(isOk) {
                ret++;
            }
        }
        return ret;
    }
}

 

 

 

 

(2) & 연산을 이용한 알고리즘

public class FanMeeting2 {
	private static BufferedReader sc = new BufferedReader(new InputStreamReader(System.in));
	private static StringBuilder builder = new StringBuilder();
	private static String M,N;
	
	public static void main(String[] args) throws Exception {
		int c = Integer.parseInt(sc.readLine());
		
		for(int i=0; i<c; i++) {
			M = sc.readLine();
			N = sc.readLine();
			builder.append(hugs(M,N)+"\n");
		}
		System.out.println("\n"+builder);
	}
	
	private static int hugs(String M, String N) {
		String strM = M.replace('M', '1').replace('F','0');
		String strN = N.replace('M', '1').replace('F','0');
		
		if(strM.length() > strN.length()) return 0;

		long A = Long.parseLong(strM,2);
		long B = Long.parseLong(strN,2);
		
        int result = 0;

        for(int i=0 ; i < strN.length() - strM.length() + 1 ; i++) {
            if ((A&B) == 0) {
                result += 1;
            }
            
            // 팬을 오른쪽으로 한 칸씩 옮긴다.
            B = (B>>1);
        }

        return result;
	}
}
저작자표시 (새창열림)

'알고리즘 (with JAVA) > 분할 정복 알고리즘' 카테고리의 다른 글

카라츠바의 빠른 곱셈 알고리즘(2) - O(N^lg3)  (1) 2022.09.14
카라츠바의 빠른 곱셈 알고리즘(1) - O(N^2)  (0) 2022.09.13
울타리 잘라내기(난이도 - 중)  (0) 2022.09.08
쿼드 트리 뒤집기(난이도 - 하)  (0) 2022.09.06
행렬의 거듭 제곱 구하기(난이도: 하)  (0) 2022.09.02
'알고리즘 (with JAVA)/분할 정복 알고리즘' 카테고리의 다른 글
  • 카라츠바의 빠른 곱셈 알고리즘(2) - O(N^lg3)
  • 카라츠바의 빠른 곱셈 알고리즘(1) - O(N^2)
  • 울타리 잘라내기(난이도 - 중)
  • 쿼드 트리 뒤집기(난이도 - 하)
백_곰
백_곰
  • 백_곰
    친절한 코딩
    백_곰
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 알고리즘 (with JAVA)
        • 기본 알고리즘
        • 완전 탐색
        • 분할 정복 알고리즘
        • 동적 계획법
        • 탐욕법
        • 코딩 테스트 기출 문제
        • 코드트리 조별과제
      • 백준 (with JAVA)
        • 완전 탐색
        • 분할 정복
        • 그 외
      • 자바
        • 개발 환경 구축하기
        • 팁
        • 기본적인 개념
        • 컬렉션 프레임워크
        • 프로세스와 쓰레드
        • 지네릭스
        • 람다식
        • 스트림
        • 입출력 IO
        • 네트워킹
        • 열거형(enums)
        • java.lang 패키지
        • java.time 패키지
        • 유용한 클래스들
        • 형식화 클래스들
      • 안드로이드 with 자바
        • 응용 문제들
        • 자잘한 문제들
        • 오류 보고서
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      코딩트리조별과제
      유용한 클래스
      Collections Framework
      snail
      불안정 정렬
      안정 정렬
      문자 기반 스트림
      TCP 소켓 프로그래밍
      다형성
      Arrays
      코딩테스트
      ServerSocket
      중간연산
      코드트리
      안드로이드 스튜디오
      선택 정렬
      map()
      outputstream
      제자리 정렬
      java.lang패키지
      알고스팟
      자바 개념
      소켓 프로그래밍
      스트림
      java.time 패키지
      역직렬화
      InputStream
      람다식
      serializable
      file
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    백_곰
    팬미팅 (난이도 - 상)
    상단으로

    티스토리툴바