[2138] 전구와 스위치

2023. 7. 18. 22:19· PS/Greedy
728x90

https://www.acmicpc.net/problem/2138

 

2138번: 전구와 스위치

N개의 스위치와 N개의 전구가 있다. 각각의 전구는 켜져 있는 상태와 꺼져 있는 상태 중 하나의 상태를 가진다. i(1 < i < N)번 스위치를 누르면 i-1, i, i+1의 세 개의 전구의 상태가 바뀐다. 즉, 꺼져

www.acmicpc.net

문제

N개의 스위치와 N개의 전구가 있다. 각각의 전구는 켜져 있는 상태와 꺼져 있는 상태 중 하나의 상태를 가진다. i(1 < i < N)번 스위치를 누르면 i-1, i, i+1의 세 개의 전구의 상태가 바뀐다. 즉, 꺼져 있는 전구는 켜지고, 켜져 있는 전구는 꺼지게 된다. 1번 스위치를 눌렀을 경우에는 1, 2번 전구의 상태가 바뀌고, N번 스위치를 눌렀을 경우에는 N-1, N번 전구의 상태가 바뀐다.

N개의 전구들의 현재 상태와 우리가 만들고자 하는 상태가 주어졌을 때, 그 상태를 만들기 위해 스위치를 최소 몇 번 누르면 되는지 알아내는 프로그램을 작성하시오.

입력

첫째 줄에 자연수 N(2 ≤ N ≤ 100,000)이 주어진다. 다음 줄에는 전구들의 현재 상태를 나타내는 숫자 N개가 공백 없이 주어진다. 그 다음 줄에는 우리가 만들고자 하는 전구들의 상태를 나타내는 숫자 N개가 공백 없이 주어진다. 0은 켜져 있는 상태, 1은 꺼져 있는 상태를 의미한다.

출력

첫째 줄에 답을 출력한다. 불가능한 경우에는 -1을 출력한다.

코드

#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>

using namespace std;

int N;
vector<int> light;
vector<int> light2;
vector<int> temp;
int ans = 0;

bool checkAns(){
	for(int i=0; i<N; ++i){
		if(light[i] != light2[i]){
			return false;
		}
	}
	return true;
}

int turn(int a){
	if(a == 0){
		return 1;
	}
	else{
		return 0;
	}
}

int main(void){
	cin >> N;

	for(int i=0; i<N; ++i){
		int a;
		scanf("%1d", &a);
		light.push_back(a);
	}

	for(int i=0; i<N; ++i){
		int a;
		scanf("%1d",&a);
		light2.push_back(a);
	}

	temp = light;

	for(int i=1; i<N; ++i){
	// i-1번째 전구를 확인
		if(light[i-1] != light2[i-1]){
			ans++;
			light[i-1] = turn(light[i-1]);
			light[i] = turn(light[i]);
			if(i != N-1){
				light[i+1] = turn(light[i+1]);
			}
		}
	}

	if(checkAns()){
		cout << ans;
		return 0;
	}

먼저 N이 10^5이기 때문에 이중 반복문을 쓰면 시간 초과가 난다 때문에 O(nlogn)이나 O(n)의 해결 방법을 찾아야 하는데

이때 생각 할 수 있는게 그리디 방법이다.

이 문제에 그리디를 어떻게 적용할까 잘 생각해보면 전구의 순서대로 불을 조정하는 것이다.

무슨 뜻이냐 하면은 만약 첫번째나 마지막 전구 이외의 다른 전구 번호의 버튼을 누르면 i-1, i, i+1번의 전구들의 불이 바뀌게 된다.

이때, i-1번의 전구만 생각하면 된다. 

i-1번의 전구에 영향을 끼치는 건 i-2번 버튼, i-1번 버튼, i번 버튼이다. i+1번의 버튼은 i-1번 전구에 영향을 줄 수 없기 때문에 무조건 i번 버튼에서 i-1번의 전구 불이 알맞게 들어야 한다.

이를 좀 더 생각해보면 첫 번째 전구에 힌트가 있다.

첫번째 전구에 영향을 주는 버튼은 첫번째 전구와 두번째 전구가 있다.

즉, 첫번째 전구를 키는 경우와 키지 않는 경우를 나눌 수 있다.

이 두경우를 나눠 불을 켜보고 만약 그럼에도 답과 맞지 않는다면 -1을 출력한다.

728x90
반응형
저작자표시 비영리 변경금지

'PS > Greedy' 카테고리의 다른 글

[1744] 수 묶기  (0) 2023.07.18
[1931] 회의실 배정  (0) 2023.05.02
[11047] 동전 0  (0) 2023.05.02
'PS/Greedy' 카테고리의 다른 글
  • [1744] 수 묶기
  • [1931] 회의실 배정
  • [11047] 동전 0
프레딕
프레딕
250x250
반응형
프레딕
소소한 해킹 블로그
프레딕
전체
오늘
어제
  • 분류 전체보기 (241)
    • etc (1)
    • PS (72)
      • Greedy (4)
      • DFS, BFS (16)
      • DP (14)
      • Stack, Queue (2)
      • 재귀 (10)
      • 이분 탐색 (1)
      • 문자열 (4)
      • 분할 정복 (2)
      • 기타 알고리즘 (19)
    • Book Review (5)
      • 알고리즘 문제 해결 전략 (3)
      • Clean Code (1)
      • The Programatic Programmer (1)
    • Web Hacking (110)
      • Webhacking.kr (42)
      • DreamHack (38)
      • Information (18)
      • Los Rubiya (1)
      • WriteUp (11)
    • Web3 (24)
      • The Ethernaut (22)
      • Information (2)
    • Reversing (18)
      • Reversing.kr (4)
      • DreamHack (3)
      • Information (11)
    • Pwnable (3)
      • DreamHack (2)
    • Misc (1)
      • PyJail (1)
    • Network (6)
    • Dev (1)
      • Flask (1)

블로그 메뉴

  • 홈
  • 태그

공지사항

인기 글

태그

  • 알고리즘
  • 시간복잡도
  • Algorithm

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
프레딕
[2138] 전구와 스위치
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.