문제 : boj21918
필요 알고리즘 개념
- 입력받기, 배열, 반복문, 조건문
- 배열에 입력을 받고 조건문과 반복문을 쓸줄 알면 된다.
- 시뮬레이션
- 별건 아니고, 그냥 구현하란 말과 동일하다. 문제에서 제시된 사항을 그대로 구현해서 그대로 실행만 되면 된다. 참고로 백준에서 '구현'태그는 대강 뭐 특별히 쓸거 없을때 달아두는 경우가 많다 ㅋㅋ 그 중에 문제에서 제시된대로 구현만 잘 하면 되는 경우 보통 시뮬레이션 태그도 같이 단다. 사람마다 다를 수 있다. 내 경우엔 그렇다.
※ 제 코드에서 왜 main 함수에 로직을 직접 작성하지 않았는지, 왜 Scanner를 쓰지 않고 BufferedReader를 사용했는지 등에 대해서는 '자바로 백준 풀 때의 팁 및 주의점' 글을 참고해주세요. 백준을 자바로 풀어보려고 시작하시는 분이나, 백준에서 자바로 풀 때의 팁을 원하시는 분들도 보시는걸 추천드립니다.
풀이
문제에서 제시된 대로만 구현해주면 되므로 딱히 풀이는 필요없을 것 같긴한데 그래도 쓸만한거 써보려 한다.
우선 일반적으로 N개의 전구 정보는 배열로 받게될 것이다. 이 때, 배열의 인덱스는 알다시피 0부터 시작하지만 문제에서 제시되는 명령어는 i번째를 뜻한다. 즉, i번째의 배열 인덱스는 i-1번이 되게 된다(예를들어 1번째는 배열에서 0번 인덱스). 그럼 그냥 배열을 N개짜리로 선언하면 매번 입력받을 때 마다 명령어들의 인덱스를 -1 해줘야 하는 번거로움이 생긴다.
그냥 단순하게 N+1개짜리 배열로 만들고, N개를 인덱스 1번부터 받아주게 되면 배열 1칸만큼의 메모리 손실은 나지만 그 뒤로 구현이 매우 편해진다. 이하 코드를 참고하자.
int[] arr = new int[n+1];
st = new StringTokenizer(br.readLine());
for (int i = 1; i <= n; i++)
arr[i] = Integer.parseInt(st.nextToken());
이후 들어오는 명령어들에 대해 a값을 기준으로 switch 또는 if 문을 통해 명령어를 구분하자. 이 때 처음 N개를 입력받은 배열을 arr이라고 하겠다.
1번 명령
-> 단순히 arr[b] = c 를 해주면 된다.
2번 명령
-> 반복문을 통해 arr[b]부터 arr[c]까지 0이면 1, 1이면 0으로 변경해주면 된다. 그렇다면 그냥 아래처럼 처리할 수 있다.
for (int i = b; i <= c; i++) {
if (arr[i] == 0)
arr[i] = 1;
else arr[i] = 0;
}
내 경우엔 arr[i]^=1 을 해줬다. '^'는 bitwise XOR(=비트단위 XOR. XOR=exclusive or)을 의미한다. XOR의 진리표는 다음과 같다. 보다시피 서로 다르다면 1, 같다면 0이다.
예를들어 X ^ Y 라면 X와 Y의 각 비트단위로 XOR을(위의 표처럼 0과 1을 비트단위로 같은 자리끼리 비교) 진행한 결과를 내준다. 예를들어 X가 4라면 0100(2)이고, Y가 6이라면 0110(2)이다. 비트단위 XOR의 결과는 0010(2)이므로 결과는 2가 될 것이다.
이 문제에서는 어차피 값 자체가 0 또는 1 이므로 bitwise XOR을 진행해도 그냥 변수 자체에 대한 XOR이라고 보면 된다. 아무튼 이걸로 왜 0이면 1, 1이면 0이 되냐면, 다음 주황색으로 칠한 부분 처럼 X ^ 1을 하게되면 X가 0일 땐 1이 되고, 1일땐 0이 되기 때문이다. 그냥 비트를 사용한 잡 기술 같은거다. 비슷한 예로 N이 짝수인지 홀수인지 판단은, N&1이 1이면 홀수, 0이면 짝수이다(bitwise AND).
3번 명령
-> 반복문을 통해 arr[b]부터 arr[c]까지 전부 0으로 변경해주면 된다.
4번 명령
-> 반복문을 통해 arr[b]부터 arr[c]까지 전부 1로 변경해주면 된다.
이후 배열의 인덱스 1번부터 사용했으므로, 1번부터 순서대로 출력해주면 된다.
코드 : github
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
private void solution() throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int[] arr = new int[n+1];
st = new StringTokenizer(br.readLine());
for (int i = 1; i <= n; i++)
arr[i] = Integer.parseInt(st.nextToken());
while (m-->0) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
switch (a) {
case 1 :
arr[b] = c;
break;
case 2 :
for (int i = b; i <= c; i++) arr[i]^=1;
break;
case 3 :
for (int i = b; i <= c; i++) arr[i] = 0;
break;
case 4 :
for (int i = b; i <= c; i++) arr[i] = 1;
break;
}
}
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= n; i++)
sb.append(arr[i]).append(' ');
System.out.println(sb);
}
public static void main(String[] args) throws Exception {
new Main().solution();
}
}
'PS > BOJ' 카테고리의 다른 글
[자바] 백준 23303 - 이 문제는 D2 입니다. (java) (0) | 2022.07.30 |
---|---|
[자바] 백준 25314 - 코딩은 체육과목 입니다 (java) (0) | 2022.07.30 |
[자바] 백준 22943 - 수 (java) (0) | 2022.07.28 |
[자바] 백준 24839 - Speed Typing (java) (0) | 2022.07.27 |
[자바] 백준 2195 - 문자열 복사 (boj java) (0) | 2022.07.26 |
댓글