-
백준 1940, 1253, 12891(JAVA)Java/코딩테스트 2022. 7. 31. 02:41
- start, end 2개의 포인트로 범위 지정해서 범위대로 이동하는 해결법으로 푸는 문제들이다.
- 오름차 순으로 정렬해서 사용하자
📌 백준 1940
📌 투 포인터 이동 원칙
- 찾고자 하는 합이 기준치보다 큰 경우에는 end쪽을 줄이고, 작은 경우에는 start쪽을 올린다(증가) : while문안에서 이 조건을 검사
- 15000이 넘지 않는 재료의 개수, 시간 제한 2초이기에 정렬을 사용할 수 있음
import java.util.*; import java.io.*; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); int m = Integer.parseInt(br.readLine()); // 엔터 기준으로 입력되기 때문에 바로 readLine후 parse int [] materials = new int[n]; StringTokenizer stringTokenizer = new StringTokenizer(br.readLine()); for (int i = 0; i < n; i++) { materials[i] = Integer.parseInt(stringTokenizer.nextToken()); } Arrays.sort(materials); // 배열 정렬 int start = 0; int end = n-1; int count = 0; while (start < end) { if (materials[start] + materials[end] > m) { end--; } else if (materials[start] + materials[end] < m) { start++; } else { count++; start++; end--; } } System.out.println(count); } }
📌 백준 1253
📌 자기 자신이 좋은 수에 포함되면 안 된다. 그래서 start와 end가 각각 i와 같은지 다른지 여부를 판단해야 한다. 이 부분 빼먹어서 실수했다.
📌 start와 end가 만나면 더 이상 수를 찾을 수 없으므로 종료조건을 이걸로 줄 것.
import java.util.*; import java.io.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int num = sc.nextInt(); int count = 0; long numbers[] = new long[num]; for (int k = 0; k < num; k++) { numbers[k] = sc.nextLong(); } Arrays.sort(numbers); for (int i = 0; i < num; i++) { int start = 0; int end = num-1; while (start < end) { if (numbers[start] + numbers[end] == numbers[i]) { if (start != i && end != i) { count++; break; } else if (start == i) { start++; } else if (end == i) { end--; } } else if(numbers[start] + numbers[end] > numbers[i]) { end--; } else { start++; } } } System.out.println(count); } }
📌 백준 12891
<tmi>
너무 복잡해서 (?) 코드 한줄한줄에 썼다. 실버2도 힘든 코딩 실력.................................
풀다가 막혀서 책 해설을 좀 찾아봤는데, removeChar함수 부분에서 stateArray와 checkArray 같은지 판별 후 checkCondition을 먼저 감소시켰어야 했는데 순서를 뒤집어서 틀렸었다. 답이 어쩐지 계속 안 나왔었다...^_^
import java.util.*; import java.io.*; public class Main { static int checkArray[]; static int stateArray[]; // ACGT 순서 static int checkCondition; public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer stringTokenizer= new StringTokenizer(reader.readLine()); int wholeLen = Integer.parseInt(stringTokenizer.nextToken()); // 전체 문자열 길이 int partLen = Integer.parseInt(stringTokenizer.nextToken()); // 부분 문자열 길이 int result = 0; checkCondition = 0; char charArray[] = new char[wholeLen]; // 전체 문자열 입력받을 배열 charArray = reader.readLine().toCharArray(); checkArray = new int[4]; // ACGT 각각 몇개 들어있어야 하는지 조건 저장 위한 배열 stateArray = new int[4]; // 지금 읽은 부분 문자열에 ACGT 몇개씩 들어있는지 상태 저장하기 위한 배열 stringTokenizer = new StringTokenizer(reader.readLine()); for (int i = 0; i < 4; i++) { checkArray[i] = Integer.parseInt(stringTokenizer.nextToken()); if (checkArray[i] == 0) { checkCondition++; // 만약 한 글자 아예 없어도 된다! 이 경우라면 condition 증가 } } for (int j = 0; j < partLen; j++) { readChar(charArray[j]); // 맨 처음 초기 partLen 만큼 먼저 읽어주고, 그 다음 한 칸씩 이동. } if (checkCondition == 4) { result++; // 처음 partLen만큼 읽었는데 만족한다면 일단 result 증가. } for (int i = partLen; i < wholeLen; i++) { int start = i - partLen; // 시작 부분, 이동하면서 맨 앞은 버리기 때문에 얘는 제거가 필요; readChar(charArray[i]); // partLen위치부터 한 칸씩 이동하면서 읽음, 이 반복문에서 i가 마지막 인덱스 removeChar(charArray[start]); if (checkCondition == 4) { result++; // 한 칸 이동할 때마다 checkCondition 만족하나 안하나 검사 } } System.out.println(result); reader.close(); } public static void readChar(char element) { switch(element) { case 'A' : stateArray[0]++; if (stateArray[0] == checkArray[0]) { checkCondition++; } break; case 'C' : stateArray[1]++; if (stateArray[1] == checkArray[1]) { checkCondition++; } break; case 'G' : stateArray[2]++; if (stateArray[2] == checkArray[2]) { checkCondition++; } break; case 'T' : stateArray[3]++; if (stateArray[3] == checkArray[3]) { checkCondition++; } break; } } public static void removeChar(char element) { switch(element) { case 'A' : if (stateArray[0] == checkArray[0]) { checkCondition--; // 현재까지의 상태가 문제 조건을 담은 배열과같을 경우에만 먼저 check조건 감소(읽으면서 증가시켰던것) } stateArray[0]--; // 그러고 나서 state 감소해야함..! 먼저 state감소시키면 정확하게 checkCondition 조정불가. break; case 'C' : if (stateArray[1] == checkArray[1]) { checkCondition--; } stateArray[1]--; break; case 'G' : if (stateArray[2] == checkArray[2]) { checkCondition--; } stateArray[2]--; break; case 'T' : if (stateArray[3] == checkArray[3]) { checkCondition--; } stateArray[3]--; break; } } }
'Java > 코딩테스트' 카테고리의 다른 글
백준 14503 (0) 2023.04.06 [ DFS / BFS ] 개념 및 예제 정리 (0) 2023.04.05 [DP] 백준 풀이 기록 JAVA (Feat. do it 알고리즘 코딩테스트) (0) 2023.04.05 백준 11003(Java) (0) 2022.08.07 백준 11659, 11660, 2018(Java) (0) 2022.07.18