[SWEA] 1230. [S/W 문제해결 기본] 8일차 - 암호문3
https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV14zIwqAHwCFAYD
https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV14zIwqAHwCFAYD
0 ~ 999999 사이의 수로 표현되는 암호문이 있고, 이 암호문을 N개 모아 놓은 암호문 뭉치가 있다.
암호문 뭉치를 급히 수정해야 할 일이 발생했는데, 암호문은 특수 제작된 처리기로만 수정이 가능하다.
처리기는 다음과 같이 3개의 명령어로 제어한다.
1. I(삽입) x, y, s : 앞에서부터 x번째 암호문 바로 다음에 y개의 암호문을 삽입한다. s는 덧붙일 암호문들이다.[ ex) I 3 2 123152 487651 ]
2. D(삭제) x, y : 앞에서부터 x번째 암호문 바로 다음부터 y개의 암호문을 삭제한다.[ ex) D 4 4 ]
3. A(추가) y, s : 암호문 뭉치 맨 뒤에 y개의 암호문을 덧붙인다. s는 덧붙일 암호문들이다. [ ex) A 2 421257 796813 ]
위의 규칙에 맞게 작성된 명령어를 나열하여 만든 문자열이 주어졌을 때, 암호문 뭉치를 수정하고, 수정된 결과의 처음 10개 암호문을 출력하는 프로그램을 작성하여라.
[입력]
첫 번째 줄 : 원본 암호문 뭉치 속 암호문의 개수 N ( 2000 ≤ N ≤ 4000 의 정수)
두 번째 줄 : 원본 암호문 뭉치
세 번째 줄 : 명령어의 개수 ( 250 ≤ M ≤ 500 의 정수)
네 번째 줄 : 명령어
위와 같은 네 줄이 한 개의 테스트 케이스이며, 총 10개의 테스트 케이스가 주어진다.
[출력]
#기호와 함께 테스트 케이스의 번호를 출력하고, 공백 문자 후 수정된 암호문 뭉치의 앞 10개 암호문을 출력한다.
[제약 사항]
실행 시간 60ms 이하
알고리즘 : 그냥 구현하는 문제
자료구조 : LinkedList
package SW문제해결기본8일차_암호문3;
import java.io.FileInputStream;
import java.util.Scanner;
// Node
class Node {
int data;
Node link;
public Node(int data) {
this.data = data;
this.link = null;
}
}
// LinkedList 클래스
class CustomLinkedList {
Node head;
int size;
public CustomLinkedList() {
this.head = null;
this.size = 0;
}
// 맨 끝에 추가 (addLast)
public void addLast(int data) {
Node node = new Node(data);
if (head == null) {
head = node;
} else {
Node curr = head;
while (curr.link != null) {
curr = curr.link;
}
curr.link = node;
}
size++;
}
// 특정 위치에 삽입 (insert)
public void insert(int index, int data) {
if (index < 0 || index > size) return; // 범위 초과 방지
Node node = new Node(data);
if (index == 0) {
node.link = head;
head = node;
} else {
Node prev = get(index - 1);
node.link = prev.link;
prev.link = node;
}
size++;
}
// 특정 위치의 노드 가져오기
public Node get(int index) {
if (index < 0 || index >= size) return null;
Node curr = head;
for (int i = 0; i < index; i++) {
curr = curr.link;
}
return curr;
}
// 특정 위치에서 삭제 (delete)
public void delete(int index) {
if (index < 0 || index >= size) return;
if (index == 0) {
head = head.link;
} else {
Node prev = get(index - 1);
prev.link = prev.link.link;
}
size--;
}
// 처음 10개 출력
public void printFirstTen() {
Node curr = head;
int count = 0;
while (curr != null && count < 10) {
System.out.print(curr.data + " ");
curr = curr.link;
count++;
}
System.out.println();
}
}
class Solution {
public static void main(String args[]) throws Exception {
System.setIn(new FileInputStream("res/문제1230암호문3.txt"));
Scanner sc = new Scanner(System.in);
int T = 10; // 테스트 케이스 개수
for (int test_case = 1; test_case <= T; test_case++) {
int N = sc.nextInt(); // 2000<=N<=4000
sc.nextLine(); // 개행 처리
String s = sc.nextLine(); // 원본 암호문
String[] sArray = s.split(" ");
// 원본 암호문을 CustomLinkedList로 변환
CustomLinkedList secrets = new CustomLinkedList();
for (String str : sArray) {
secrets.addLast(Integer.parseInt(str));
}
int M = sc.nextInt(); // 250<=M<=500
sc.nextLine();
String order = sc.nextLine(); // 명령어 한 줄 읽기
String[] parts = order.split(" ");
int i = 0; // parts 배열의 인덱스
while (i < parts.length) {
// 명령어 처리
switch (parts[i]) {
case "I": // Insert
int index = Integer.parseInt(parts[i + 1]);
int count = Integer.parseInt(parts[i + 2]);
for (int j = 0; j < count; j++) {
secrets.insert(index + j, Integer.parseInt(parts[i + 3 + j])); // index 위치에 삽입
}
i = i + 3 + count; // 명령어 처리 후 i 업데이트 (i + index + count + ~~~) 이렇게 해서 3개
break;
case "D": // Delete
int delIndex = Integer.parseInt(parts[i + 1]);
int delCount = Integer.parseInt(parts[i + 2]);
for (int j = 0; j < delCount; j++) {
secrets.delete(delIndex); // delIndex 위치에서 삭제
}
i = i + 3; // 명령어 처리 후 i 업데이트
break;
case "A": // Append
int appendCount = Integer.parseInt(parts[i + 1]);
for (int j = 0; j < appendCount; j++) {
secrets.addLast(Integer.parseInt(parts[i + 2 + j])); // 끝에 추가
}
i = i + 2 + appendCount; // 명령어 처리 후 i 업데이트
break;
}
}
// 결과 출력 (첫 10개 값만 출력)
System.out.print("#" + test_case + " ");
secrets.printFirstTen();
}
sc.close();
}
}