문자열 분리 문제이다. 문자열 분리 방법만 안다면 크게 어렵지 않은 문제라고 필자는 생각합니다.
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int[] arr = new int[10];
int index = Integer.parseInt(br.readLine()) * Integer.parseInt(br.readLine()) * Integer.parseInt(br.readLine());
String str = String.valueOf(index);
for (int i = 0; i < str.length(); i++) {
arr[(str.charAt(i) - 48)]++;
}
for (int v : arr) {
System.out.println(v);
}
}
}
먼저, 0부터 9까지 체크할 길이 10의 int 배열을 생성 (기본 int배열 초기값은 모두 0이다.)
그리고 index 에다가 br.readLine() 으로 읽은 값을 곱해서 저장한다.
그리고 String str 에다가 index 의 Int 형을 String 형으로 변환해준 뒤
for문을 통해 해당 문자열의 문자 값 - 48 (또는 -'0')을 추출해내 int 배열의 index 값을 1 증가시킨다.
문자 값에 48을 뺴주는 이유 : 아스키 코드
getBytes()
메소드는 입력 문자열을 byte 단위의 배열로 반환시켜주는 메소드
그리고 중요한 키 포인트는 배열
로 반환을 하므로 for-each 문에서도 쓸 수 있다는 점이 있습니다.
(자세한 설명)
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int test_case = Integer.parseInt(br.readLine()); // 테스트 케이스
for (int i = 0; i < test_case; i++) {
int count = 0; // 연속횟수
int sum = 0; // 누적 합산
for (byte value : br.readLine().getBytes()) {
if (value == 'O') {
count++;
sum += count;
}
else {
count = 0;
}
}
sb.append(sum).append('\n');
}
System.out.println(sb);
}
}
보통 배열로 푸는 문제입니다.
그러나 더 좋은 방법인 HashSet
이라는 자바 Collection 중 Set 의 파생클래스
를 사용하는 것입니다. (set은 히스토그램의 집합이라고 생각하면 됌)
HashSet
1) 중복 되는 원소를 넣을 경우 하나만 저장합니다. 즉. 중복원소를 허용하지 않습니다.
2) HashSet은 순서 개념이 없습니다. 따라서 Collections.sort()메소드를 사용할 수 없습니다.
만약 정렬 하고 싶다면 리스트로 변환 후 정렬해야합니다.
이 문제에서는 결국 나머지 값에서 "서로 다른" 개수를 세면 되는 것이기 때문에
HashSet 을 이용하면 자연스럽게 나머지 값이 HashSet 원소에 이미 저장되어있어
중복일 경우 저장이 되지 않고 HashSet 에 없으면 저장하게 됩니다.
즉, HashSet 에 저장하면서 들어간 원소의 개수가 HashSet 의 사이즈가 되는 것이고,
이는 결국 "서로 다른 나머지"가 되는 것입니다.
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
HashSet<Integer> hashSet = new HashSet<Integer>();
for (int i = 0; i < 10; i++) {
hashSet.add(Integer.parseInt(br.readLine()) % 42);
}
System.out.println(hashSet.size());
}
}
HashSet.add()
메소드는 HashSet에 저장하는 메소드입니다,HashSet.size()
는 HashSet 의 크기(= 저장되어 있는 원소의 개수)를 반환합니다.2번째, 배열 풀이)
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
boolean[] arr = new boolean[42];
for (int i = 0; i < 10; i++) {
arr[Integer.parseInt(br.readLine()) % 42] = true;
}
int count = 0;
for (boolean value : arr) {
// value 가 true 라면
if (value) {
count++;
}
}
System.out.println(count);
}
}
공백 단위로 처리할 때 그냥 공백의 개수대로 단어를 세아리면 예외가 발생할 수 있습니다.
왜냐하면 문자열의 앞과 뒤에는 공백이 있을 수도 있기 때문입니다.
또한, countTokens()
메서드를 알았다면 쉽게 풀 수 있는 문제입니다.
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
System.out.print(st.countTokens());
}
}
근데, 코테중에 이 토큰카운트 메서드가 기억 안날 경우도 있으니, 입력 형태 그대로 하나씩 읽어들인 문자가 공백인지 아닌지에 count 하는 방법을 소개해드리겠습니다.
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
int count = 0;
//문자를 저장하기위해 초기화
int str = 32; //공백
// 현재 입력받은 문자를 저장할거임
int index;
while (true) {
// 입력 받은 값을 읽어들임
index = System.in.read();
// 입력 받은 문자가 공백일 경우
if (index == 32) {
// 이전 문자가 공백이 아니라면
if (str != 32) {
count++;
}
}
// // 입력 받은 문자가 개행일 경우 ('\n')
else if (index ==10) {
// 이전 문자가 공백이 아니라면
if (str != 32) {
count++;
break;
}
}
str = index;
}
System.out.print(count);
}
}
주의 !, 첫 문자와 마지막 문자가 공백이라면 count 변수가 1이 증가하기 때문에 예외를 발생시키지 않기위해,
공백을 입력받을 경우 count 를 1 증가시키지 않고 추가 조건이 붙어 이전의 문자가 공백이 아닐 경우도 포함할 때만 1 증가시키면 됩니다.
{
생략이 가능하다. 이것을 잘 활용하면 디버깅 시간을 줄일 수 있습니다. (메모리를 덜 잡아먹어서) split()
메소드 사용하면 수월합니다.
or StringTokenizer을 사용해서 풀면 됩니다. -> (필수) 숫자와 문자열 사이의 공백 구분
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
for (int i = 0; i < T; i++) {
String[] str = br.readLine().split(" "); // split 사용으로 공백 분리해줌
// 문자열 string -> int 로 수정
int R = Integer.parseInt(str[0]);
String S = str[1];
// S 배열 길이만큼 반복해서 출력
for (int j = 0; j < S.length(); j++) {
for (int k = 0; k < R; k++) {
// j 문자 반복 chartAt() 메서드 사용
System.out.print(S.charAt(j));
}
}
System.out.print('\n');
}
}
}
입력 받은 문자열을 뒤집을 수 있어야합니다.
1. 배열을 이용
2. StringBuilder 의 reverse() 메소드
를 이용하여 문자를 뒤집기
3. 입력 자체를 한 문자씩 읽어들여 수식을 완성시키는 방법
필자는 2번 방식으로 풀이할 예정입니다.
StringBuilder 는
문자열을 다루는 클래스로 많이 쓰이고 있는데, 여기서 reverse()
라는 아주 좋은 메소드를 포함하고 있습니다.
사용하기 위해 먼저 StringBuilder 생성과 동시에 append()
라는 메소드에 값을 넣어줘야하며, 이때 append() 로 넣어진 값은 타입이 StringBuilder 라는타입으로 변환됩니다.
그리고 그렇게 저장된 수를 reverse()
라는 메소드를 통해 저장되어있던 문자열을 뒤집는다. 그리고 StringBuilder 타입을 문자열로 반환시키기 위해 toString()
을 써주면 끝이다.
그리고 문자열로 반환시켰으니 Integer.parseInt() 로 String 을 int 로 타입을 변경하면 끝입니다.
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 토큰을 생성해서 띄어쓰기로 각 토큰을 나눠줌
StringTokenizer st = new StringTokenizer(br.readLine()," ");
// 나눠준 토큰을 StringBuilder의 reverse() 메소드를 사용해서 문자열을 뒤집어줌.
// 그리고 StringBuilder 타입을 문자열로 반환시키기 위해 toString()메소드 사용.
// 이후 Integer.parseInt()로 문자열을 다시 숫자로 바꿔줌
int A = Integer.parseInt(new StringBuilder(st.nextToken()).reverse().toString());
int B = Integer.parseInt(new StringBuilder(st.nextToken()).reverse().toString());
System.out.print(A > B ? A:B);
}
}
1번 풀이와 차이점을 보면 객체를 생성할 때 문자열 인자를 바로 넣어줄 수 있다는 점이 다르다.
1번 풀이는 Scanner 을 사용하여 int 타입으로 받았기 때문에,
객체를 생성할 때 append() 메소드를 써야했지만
만약 넣어주려는 인자가 String 타입이면 append() 를 사용할 필요가 없습니다.
- 배열을 이용해서 정렬
Arrays.sort()
메소드 사용
//1
//초기화된 배열 가정해서 문제접근
int[] arr;
for(int i = 0; i < arr.length - 1; i++) {
for(int j = i + 1; j < arr.length; j++) {
if(arr[i] > arr[j]) {
// 값 교환
int temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
// 코드
import java.io.*;
import java.math.BigInteger;
import java.util.*;
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[] arr = new int[N];
for(int i = 0; i < N; i++) {
arr[i] = Integer.parseInt(br.readLine());
}
//소팅
for(int i = 0; i < N - 1; i++) {
for(int j = i + 1; j < N; j++) {
if(arr[i] > arr[j]) {
int temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
for(int val : arr) {
System.out.println(val);
}
}
}
이 방법을 이용해서 코드를 작성하면
//2
import java.io.*;
import java.math.BigInteger;
import java.util.*;
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[] arr = new int[N];
for(int i = 0; i < N; i++) {
arr[i] = Integer.parseInt(br.readLine());
}
// 정렬 메소드, 정렬해줌
Arrays.sort(arr);
// 출력문
for(int val : arr) {
System.out.println(val);
}
}
}
java.util.Arrays 유틸리티 클래스를 사용하면 배열(Array)을 정렬, 복제하거나, List로 변환 하는 등의 작업을 쉽게 처리 할 수 있습니다.
해당 클래스의 sort()
메서드를 사용하면 쉽게 오름차순 정렬이 가능합니다.
sort()
메서드는 클래스 메서드(Class method / Static method)로서 Arrays 클래스의 인스턴스 생성없이 바로 사용하시면 됩니다.
int[] intArr = new int[] {1,3,5,2,4};
Arrays.sort(intArr,2,5); // intArr[2]~intArr[4]의 값 (5,2,4) 만 정렬 (toIndex 이전 index까지)
class Test{
long sum(int []a ){
long sum = 0;
for (int i = 0; i < a.length; i++) {
sum += a[i];
}
// a 배열에 저장되어있는 정수들을 더하여 long 타입 형으로 돌려줌
return sum;
}
}
필자도 생각을 많이하고 어려워했던 문제입니다. 단순 노가다로 풀었고, 시간은 정말 오래걸리게 되었습니다. 그리하여 다른 블로그의 도움을 받고, 이해하게 되었습니다.
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// A(1년 고정료) = 임대료 + 재산세 + 보험료 + 급여
// B(1대 노트북 생산비용) = 재료비 + 인건비
// 손익 분기점 구하기
// 출력 값은 최초 이익 발생 판매량 존재하지 않을경우 -1
// C = 노트북 가격
StringTokenizer st = new StringTokenizer(br.readLine());
int A = Integer.parseInt(st.nextToken());
int B = Integer.parseInt(st.nextToken());
int C = Integer.parseInt(st.nextToken());
// (C - B) = 1대당 나의 순수익으로 생각해서 로직을 짜게되면 어렵다 정말 어렵다.
// 따라서, n=개당개수 일때, 총비용과 총수입이 같아지는 식, n*C = A + (B*n)
// 따라서 순익분기점이 발생하는 판매량의 개수 식은 n= A/C-B +1 입니다.
// 여기서 왜 1을 더해주냐면 부등식이 같을 경우에는 순익 분기점이 발생하는 시점이 아니고,
// 0원 즉 이익이 없는 손해도 없는 그런 상태를 말합니다. 그래서 +1을 더해주면 순익이 발생합니다.
if (C-B<=0) {
System.out.print("-1");
}else System.out.print(A/(C-B)+1);
}
}
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 문자열로 받고 문자열로 받은 것을 문자로 하나씩 인식해서 그 인식 번호가 w는 9번 -> 스위치문 써서 더해줌
String s = br.readLine();
int count =0;
int t = s.length();
for (int i = 0; i < t; i++) {
switch (s.charAt(i)) {
case 'A' : case 'B': case 'C' :
count += 3;
break;
case 'D' : case 'E': case 'F' :
count += 4;
break;
case 'G' : case 'H': case 'I' :
count += 5;
break;
case 'J' : case 'K': case 'L' :
count += 6;
break;
case 'M' : case 'N': case 'O' :
count += 7;
break;
case 'P' : case 'Q': case 'R' : case 'S' :
count += 8;
break;
case 'T' : case 'U': case 'V' :
count += 9;
break;
case 'W' : case 'X': case 'Y' : case 'Z' :
count += 10;
break;
}
}
System.out.println(count);
}
}
long 타입을 주의해야한다.
필자도 int 타입으로 문제를 풀었었는데, 틀렸을 때 이유가 나의 풀이법에 있는 줄 알고 여러번 수정하였으나, 문제의 입력 값을 보게 되면 INT 범위를 초과한 것이 보일 것이다. 따라서 int 타입이 아닌 long 타입으로 작성해주면 된다.
import java.io.*;
import java.math.BigInteger;
import java.util.*;
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());
// 줄바꿈을 해줘야 하기 때문에, 일단 정의만 해둠. 초기화는 나중에 할 예정 (줄 바꿀때)
StringTokenizer st;
// 감독 초기화
long supervisor = 0;
// 각 시험장 배열로 표현,
int[] arr = new int[N];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) {
// 배열 인덱스 번호 = 시험장의 넘버.
arr[i] = Integer.parseInt(st.nextToken());
}
st = new StringTokenizer(br.readLine());
int B = Integer.parseInt(st.nextToken());
int C = Integer.parseInt(st.nextToken());
// 시험장 갯수만큼 감독수도 늘려줘야함 -> 각각의 시험장에 총감독관 1명만 필수요소 == 시험장 갯수
supervisor += N;
for (int i = 0; i < N; i++) {
// 총 감독관이 감독할 수 있는 시험장만큼 시험장을 빼줌 시험장 (시험장 == arr[])배열
arr[i] -= B;
//부 감독관 넣기.
if (arr[i]<=0) continue;
supervisor += arr[i] / C;
// 딱 맞지 않을 경우 1명 더 추가
if (arr[i] % C != 0) {
supervisor++;
}
}
System.out.print(supervisor);
}
}
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
StringTokenizer st;
for (int i = 0; i < T; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
// 10 번 데이터는 10번 컴퓨터
if (a % 10 == 0) {
System.out.println(10);
continue;
}
// a 에 b 제곱을 구하여 뒷자리만 쓰면 됨
// 숫자를 표한할 수 있는 자리수가 정해져 있기 때문에,
// 제곱을 구할때 마다 10으로 나눈 나머지만 가지고 계산해야 범위 내까지 계산 가능함.
int sum = 1;
for (int j = 0; j < b; j++) {
sum = (sum * a) % 10;
}
System.out.println(sum);
}
}
}
import java.io.*;
import java.math.BigInteger;
import java.util.*;
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 dollar = 1000;
int total;
total = dollar - n;
int count=0;
if (total / 500 > 0) {
count++;
}
if ((total % 500)/100 >0) {
count += (total % 500) / 100;
}
if (((total % 500) % 100) / 50 > 0) {
count += ((total % 500) % 100) / 50;
}
if ((((total % 500) % 100) % 50) / 10 > 0) {
count += (((total % 500) % 100) % 50) / 10;
}
if (((((total % 500) % 100) % 50) % 10) / 5 > 0) {
count += ((((total % 500) % 100) % 50) % 10) / 5;
}
if ((((((total % 500) % 100) % 50) % 10) % 5)/1 > 0) {
count += (((((total % 500) % 100) % 50) % 10) % 5) / 1;
}
System.out.println(count);
}
}
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 문제를 이해하면, 생성자의 경우에는 1개 이상이기 때문에 최솟값을 찾기 위해서는 작은 수 부터 찾아야한다는 것을 알 수 있다.
// 가장 기본적인 방법으로는 1 부터 입력받은 N 까지 한 개씩 모두 대입해보는 것입니다.
// 참고로 이 방법은 브루트포스의 대표적인 방식입니다.
int N = Integer.parseInt(br.readLine());
int total = 0;
for (int i = 0; i < N; i++) {
int num = i;
// 각 자릿수 합 초기화
int sum = 0;
while (num != 0) {
// 각 자릿수 더해주기 위해서 %10 해줘서 나머지 값만 더해주면 됨.
sum += num % 10;
num /= 10;
}
// 생성자 찾았을 경우, i 값과 각 자릿수 누적 합이 같을 경우
if (sum + i == N) {
total = i;
break;
}
}
System.out.print(total);
}
}
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
// 피보나치 문제, 참고로 int 기본값 0
//이 문제는 DP(다이나믹 프로그래밍)를 이용하면 효율적으로 풀 수 있다. 우선 N을 입력받는다.
// 그리고 N의 범위가 45까지이다 보니 크기가 46인 int 형 배열 dp를 만들어주고 dp [1]은 1로 초기화
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
int[] dp = new int[46];
dp[1]=1;
for (int i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
System.out.print(dp[n]);
}
}
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine();
// 리버스 메서드 사용하기 위해서 stringBuilder 로 초기화
StringBuilder sb = new StringBuilder(str);
if (str.equals(sb.reverse().toString())) {
System.out.print(1);
} else {
System.out.print(0);
}
}
}