1. 문제

알파벳 소문자, 대문자, 숫자 0-9중 하나가 주어졌을 때, 주어진 글자의 아스키 코드값을 출력하는 프로그램을 작성하시오.

 

2. 코드

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        char c = sc.next().charAt(0);
        System.out.println((int)c);
        sc.close();
    }
}

 

3. 풀이

char형으로 입력받아서 int형으로 출력하기! 

JAVA는 char형으로 바로 입력받을 수 없다는 것이 문제!

sc.next()는 문자열 입력이기 때문에 charAt이라는 메소드를 사용해야 한다

charAt(0)은 문자열의 첫번째 원소를 뜻하므로 문자 하나만 저장할 수 있게 된다. 만약에 next()만 사용하면, 문자를 하나 입력했다하더라도 null값과 함께 저장이 되기 때문에 "문자열"에 저장하라는 에러 메시지가 뜨게 된다.  

 

4. 링크

www.acmicpc.net/problem/11654

 

11654번: 아스키 코드

알파벳 소문자, 대문자, 숫자 0-9중 하나가 주어졌을 때, 주어진 글자의 아스키 코드값을 출력하는 프로그램을 작성하시오.

www.acmicpc.net

 

1. 문제

어떤 양의 정수 X의 각 자리가 등차수열을 이룬다면, 그 수를 한수라고 한다. 등차수열은 연속된 두 개의 수의 차이가 일정한 수열을 말한다. N이 주어졌을 때, 1보다 크거나 같고, N보다 작거나 같은 한수의 개수를 출력하는 프로그램을 작성하시오. 

 

--- More Details ---

등차수열이란?

연속하는 두 항의 차이가 모두 일정한 수열

식으로 나타내면 다음과 같다.

한수란?

각 자리수들이 등차수열을 이루는 수

 

한수의 예를 들어보면, 

123(공차 1) , 2468(공차 2) , 951(공차 -4), 등등이 있다. 

세자리 수 이상인 수는 이렇게 쉽게 한수를 생각해 낼 수 있는데, 한자리수와 두자리수는 한수를 어떻게 구할까?

한자리수와 두자리수는 모두 한수이다.

한자리수인 경우,(1,2,3,4...9) 따로 비교할 숫자가 없기 때문에 그 자체로 한수라 한다. 뭐 그래도 한수인 이유를 굳이 살펴보자면,  01(공차1) 02(공차2)... 09(공차9) 라고 볼수 있다. 
두자리수인 경우, 십의자리와 일의자리의 차가 공차가 되면서 한수라 할 수 있다. 10(공차 -1) 48(공차 4) 92(공차 -7)...  

따라서 모든 한자리수와 두자리수는 한수이다. 이점에 유의하며 문제를 풀어야 한다

 

추가로 11, 22, 99, 333, 이 수들은 한수일까?맞다. 공차가 0인 한수들이다.

 

2. 알고리즘 및 풀이

나는 함수를 main, getDigits, arithmetic_sequence함수 이렇게 세개 만들었다.

main은 말 그대로 main함수

getDigits함수는 각 자릿수를 뽑아내는 함수로, int형 배열을 반환한다.

arithmetic_sequence함수는 등차수열(arithmetic_sequence)인지 아닌지를 판별하는 함수이다.

 

getDigits함수 (각 자릿수 뽑아내어 배열로 저장하기)

public static int[] getDigits(int n){
		int[] digits= new int[3];
		for(int i=0;i<3;i++) {
			digits[i]=n%10;
			n=n/10;
		}
		
	    return digits;

	}

이제는 바로바로 짤 수 있어야 하는 함수중에 하나이다. 일단 문제에서 n은 1000이하의 수라 하였고, 우리가 100미만인 수(한자리수와 두자리수)는 따로 계산하고, 1000은 한수가 아니기 때문에 세자리수만 판정하면 된다. 따라서 각 자릿수를 얻는 것 또한 세자리 수만 계산할 것이기 때문에 digits배열은 크기가 3이면 된다.

일의자리부터 10을 나눈 나머지를 배열[0]에 저장하고, 10을 나누어 몫만 다시 n에 저장하고, ... 이렇게 반복하면된다.

246을 예로들어 표현하면

더보기

i=0일때, 246%10 = 6 이므로, digits[0]=6, n=(246/10=)24 

i=1일 때, 24%10 = 4 이므로, digits[1]=4, n=(24/10=)2 

i=2일때, 2%10=2 이므로 digits[2] = 2, n=(2/10=)0 

반복문 종료

그리고 getDigits함수는 digits배열을 반환한다. 

 

arithmetic_sequence 함수 (각 자리수가 등차수열인지 아닌지 판별하기)

한수(각 자릿수가 등차수열인 수)이면 cnt=1을 저장하여 반환한다.

1. 100미만의 수(한자리수, 두자리수)는 한수이므로 cnt=1이다.

2. n이 1000이라면 한수가 아니기때문에, cnt=0이다. 0이 아닌 다른수로 저장해도 상관없다.

3. 그 외(세자리수) getDigits함수를 통해 각 자릿수를 저장한 배열을 불러와 등차수열인지 아닌지 판별한다.

등차수열을 판별하는 방법은 (세자리수-두자리수) 와 (두자리수-한자리수)가 같으면 된다. 거꾸로 (한자리수 - 두자리수) 와 (두자리수 - 세자리수)가 같으면 된다. 즉, 연속된 수의 공차가 같으면 된다. 공차가 동일하면 cnt=1이다. 

public static int arithmetic_sequence(int n) {
		
		int cnt=0;
		if(n<100) cnt=1;
		else if(n==1000)	cnt=0;
		else {
			int[] digits = getDigits(n);
			if(digits[2]-digits[1]==digits[1]-digits[0])	cnt=1;
		}
		return cnt;
		
	}

 

main함수

int n = sc.nextInt();
int result=0;	//result: 한수의 개수를 저장
for(int i=1;i<=n;i++) {
	if(arithmetic_sequence(i)==1) result++;
}
System.out.println(result);

n에 숫자를 입력 받아 저장하고 1부터 n까지 반복문을 돌려 cnt의 개수, 즉 한수의 개수를 세어주면 된다. arithmetic_sequence함수를 불러 그 함수가 반환하는 값이 1이면 한수이므로 result를 1 증가 시키면 된다.

 

 

3. 전체 코드

import java.util.Scanner;
public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int result=0;
		for(int i=1;i<=n;i++) {
			if(arithmetic_sequence(i)==1) result++;
		}
		System.out.println(result);
		sc.close();
		
	}
	
	public static int[] getDigits(int n){
		int[] digits= new int[3];
		for(int i=0;i<3;i++) {
			digits[i]=n%10;
			n=n/10;
		}
		
	    return digits;

	}
	
	public static int arithmetic_sequence(int n) {
		
		int cnt=0;
		if(n<100) cnt=1;
		else if(n==1000)	cnt=0;
		else {
			int[] digits = getDigits(n);
			if(digits[2]-digits[1]==digits[1]-digits[0])	cnt=1;
		}
		return cnt;
		
	}
}

 

4. 링크

www.acmicpc.net/problem/1065

 

1065번: 한수

어떤 양의 정수 X의 각 자리가 등차수열을 이룬다면, 그 수를 한수라고 한다. 등차수열은 연속된 두 개의 수의 차이가 일정한 수열을 말한다. N이 주어졌을 때, 1보다 크거나 같고, N보다 작거나

www.acmicpc.net

 

1. 문제

셀프 넘버는 1949년 인도 수학자 D.R. Kaprekar가 이름 붙였다. 양의 정수 n에 대해서 d(n)을 n과 n의 각 자리수를 더하는 함수라고 정의하자. 예를 들어, d(75) = 75+7+5 = 87이다.

양의 정수 n이 주어졌을 때, 이 수를 시작해서 n, d(n), d(d(n)), d(d(d(n))), ...과 같은 무한 수열을 만들 수 있다. 

예를 들어, 33으로 시작한다면 다음 수는 33 + 3 + 3 = 39이고, 그 다음 수는 39 + 3 + 9 = 51, 다음 수는 51 + 5 + 1 = 57이다. 이런식으로 다음과 같은 수열을 만들 수 있다.

33, 39, 51, 57, 69, 84, 96, 111, 114, 120, 123, 129, 141, ...

n을 d(n)의 생성자라고 한다. 위의 수열에서 33은 39의 생성자이고, 39는 51의 생성자, 51은 57의 생성자이다. 생성자가 한 개보다 많은 경우도 있다. 예를 들어, 101은 생성자가 2개(91과 100) 있다. 

생성자가 없는 숫자를 셀프 넘버라고 한다. 100보다 작은 셀프 넘버는 총 13개가 있다. 1, 3, 5, 7, 9, 20, 31, 42, 53, 64, 75, 86, 97

10000보다 작거나 같은 셀프 넘버를 한 줄에 하나씩 출력하는 프로그램을 작성하시오.

 

2. 코드

public class Main{
    public static void main(String[] args){
        boolean[] check = new boolean[10001];
        for(int i=1;i<10001;i++){
            int n = d(i);
            if(n<10001)	check[n]=true;
        }
        
        for(int i=1;i<10001;i++){
            if (check[i]==false)    System.out.println(i);
        }
        
    }

public static int d(int n){
    int cnt=n;
    while(n!=0){
        cnt = cnt + (n%10);
        n = n/10;
    }
    	return cnt;
	}
}

 

3. 풀이

d 함수는 n과 각 자리수를 더하는 함수이다.

d함수에 대한 설명은 아래 주석으로 달아놓았다.

public static int d(int n){
    int cnt=n;	//cnt는 n과 각 자릿수를 더한 값을 저장하기 위한 변수
    //cnt의 초기값을 n으로 한다.
    
    while(n!=0){
        cnt = cnt + (n%10);
        //기존의 cnt값에 n의 일의 자리수를 더해 저장한다. 
        //cnt의 초기값을 n으로 설정한 이유이다.
        
        n = n/10;
        //일의자리를 없애준다. 
    }
    	return cnt;	
	}
}

n/10을 함으로써 일의 자리를 없앤다는 것은 계산을 해보면 알겠지만,

1234 -> 123 -> 12 -> 1 -> 0 이렇게 된다. 

 

main함수로 돌아가면..

public class Main{
    public static void main(String[] args){
        boolean[] check = new boolean[10001];
        // true false값을 저장하는 bool타입 배열을 선언한다.
        
        for(int i=1;i<10001;i++){
            int n = d(i);	//i와 각 자릿수를 더한 값을 계산한 값을 n에 저장한다.
            
            if(n<10001)	check[n]=true;
            //결과값들 중에서 10001보다 작은 값들만 true로 설정한다. 
            
        }
        
        for(int i=1;i<10001;i++){
        	//false인 값들만 출력한다. -> false인 값들은 당연히 d함수를 통해 반환되지 않는 값들이다.
            if (check[i]==false)    System.out.println(i);
        }
        
    }

※ boolean 배열의 크기가 10001인 이유

이후 반복문에서 1에서 10000까지의 인덱스 숫자를 쓸 것이므로, check[10000]의 값을 저장하기 위해서는 배열의 크기를 [10001]로 설정해 주어야 한다.

 

 if(n<10001) check[n]=true; 인 이유

만약 n 20000이라는 숫자가 나왔을때, if문이 없어 그대로 check[n]=true;라 실행했다면 , "java.lang.ArrayIndexOutOfBoundsException" 에러가 발생할 것이다. 즉, 배열의 인덱스 값이 범위를 넘어설 것이다. check 배열의 크기는 10001으로 설정되어있기때문에 n의 값이 10001보다 작은 경우에만 해당 실행문이 실행되도록 하면 된다. 

백준에서 실행시키게 되면 "런타임 에러"가 발생할 것이다. 

 

 

 

 

4. 링크

www.acmicpc.net/problem/4673

 

4673번: 셀프 넘버

셀프 넘버는 1949년 인도 수학자 D.R. Kaprekar가 이름 붙였다. 양의 정수 n에 대해서 d(n)을 n과 n의 각 자리수를 더하는 함수라고 정의하자. 예를 들어, d(75) = 75+7+5 = 87이다. 양의 정수 n이 주어졌을 때,

www.acmicpc.net

 

1. 문제

대학생 새내기들의 90%는 자신이 반에서 평균은 넘는다고 생각한다. 당신은 그들에게 슬픈 진실을 알려줘야 한다.

 

<입력>

첫째 줄에는 테스트 케이스의 개수 C가 주어진다.

둘째 줄부터 각 테스트 케이스마다 학생의 수 N(1 ≤ N ≤ 1000, N은 정수)이 첫 수로 주어지고, 이어서 N명의 점수가 주어진다. 점수는 0보다 크거나 같고, 100보다 작거나 같은 정수이다.

 

<출력>

각 케이스마다 한 줄씩 평균을 넘는 학생들의 비율을 반올림하여 소수점 셋째 자리까지 출력한다.

 

2. 코드

import java.util.Scanner;
public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int sum=0, cnt=0;
		int c =sc.nextInt();
		for(int i=0;i<c;i++) {
			int n = sc.nextInt();
			int[] score= new int[n];
			for(int j=0;j<n;j++) {
				score[j]=sc.nextInt();
				sum+=score[j];
			}
			double avr = sum/n;		
			for(int j=0;j<n;j++) {
				if(score[j]>avr)cnt++;
			}
			System.out.print(String.format("%.3f",(float)cnt/n*100));
			System.out.println("%");
			cnt=0;sum=0;
		}
		
		sc.close();
	}

}

 

3. 풀이

내가 가장 애를 먹었던 부분은 "소수 셋째자리까지 출력"하는 것이었다. 

일단 그 방법에 대해 설명하자면, String.format() 메소드를 사용한다!

String클래스의 format 메소드는 리턴되는 문자열 형태를 지정하는 함수이다. 

String.format(format,args)형태로 사용한다.

위의 코드를 예로 들어 설명하면, (cnt/n*100)을 소수 셋째자리까지 나타내는 것 이므로

String.format("%.3f",(float)cnt/n*100) 라고 쓴다.

 

 

4. 링크

www.acmicpc.net/problem/4344

 

4344번: 평균은 넘겠지

대학생 새내기들의 90%는 자신이 반에서 평균은 넘는다고 생각한다. 당신은 그들에게 슬픈 진실을 알려줘야 한다.

www.acmicpc.net

 

<참고>

bskwak.tistory.com/191

 

[JAVA] 소수점 n번째 자리까지 반올림하여 나타내기

소수점 n번째 자리까지 나타내는 방법에는 2가지가 있다. 첫번째로, Math.round()함수를 이용하는 방법 두번째로, String.format()함수를 이용하는 방법 1. Math.round()함수 round함수는 소수점 첫번째 자리

bskwak.tistory.com

 

1. 문제

"OOXXOXXOOO"와 같은 OX퀴즈의 결과가 있다. O는 문제를 맞은 것이고, X는 문제를 틀린 것이다. 문제를 맞은 경우 그 문제의 점수는 그 문제까지 연속된 O의 개수가 된다. 예를 들어, 10번 문제의 점수는 3이 된다.

"OOXXOXXOOO"의 점수는 1+2+0+0+1+0+0+1+2+3 = 10점이다.

OX퀴즈의 결과가 주어졌을 때, 점수를 구하는 프로그램을 작성하시오.

 

2. 코드

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String test;
        int score=0;int cnt=0;
        for(int i=0;i<n;i++){
        	test=sc.next();
        	char[] testArr = test.toCharArray();
        	for(int j=0;j<testArr.length;j++) {
        		if(testArr[j]=='O') {
        			cnt++;
        		}else cnt=0;
        		score=cnt+score;
        	}
        	System.out.println(score);
        	score=0; cnt=0;
        }
        
        }
    }

 

3. 풀이

cnt와 score 변수를 이용하여 해당 점수를 출력할 것이다. 

n은 테스트의 수 이므로, 가장 바깥 반복문에서 사용한다. 각 테스트는 안쪽 반복문에서 사용해야하고, 0부터 배열의 크기만큼 반복문을 돈다.  

각 테스트의 점수를 계산하기 전에, test변수에 원하는 "OXOX..."를 문자열로 입력받은 후, "toCharArray()"메소드를 통해 문자열을 char형 배열로 변환한다. 

cnt는 배열의 각 원소를 지날때마다 score에 더하는 점수로, O가 연속으로 나오면 cnt는 1씩 증가하고, X가 나오면 0으로 초기화 된다. 안쪽반복문을 끝낸 후에(한 테스트 케이스 점수를 계산한 후에)는 score과 cnt 모두 0으로 초기화 해야한다. 

 

4. 링크

www.acmicpc.net/problem/8958

 

8958번: OX퀴즈

"OOXXOXXOOO"와 같은 OX퀴즈의 결과가 있다. O는 문제를 맞은 것이고, X는 문제를 틀린 것이다. 문제를 맞은 경우 그 문제의 점수는 그 문제까지 연속된 O의 개수가 된다. 예를 들어, 10번 문제의 점수

www.acmicpc.net

 

1. 문제

세준이는 기말고사를 망쳤다. 세준이는 점수를 조작해서 집에 가져가기로 했다. 일단 세준이는 자기 점수 중에 최댓값을 골랐다. 이 값을 M이라고 한다. 그리고 나서 모든 점수를 점수/M*100으로 고쳤다.

예를 들어, 세준이의 최고점이 70이고, 수학점수가 50이었으면 수학점수는 50/70*100이 되어 71.43점이 된다.

세준이의 성적을 위의 방법대로 새로 계산했을 때, 새로운 평균을 구하는 프로그램을 작성하시오.

 

2. 코드

import java.util.Scanner;
import java.util.Arrays;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int sum=0;
        int[] score = new int[n];
        for (int i=0;i<n;i++){
            score[i]=sc.nextInt();
            sum+=score[i];
        }
        Arrays.sort(score);
        System.out.println((float)(sum*100)/(n*score[n-1]));
        sc.close();
        
    }
}

 

3. 풀이

현재 각각의 점수에 최고점을 나누고 100을 곱한 것이 조작한 점수이다.

즉, 현재 점수를 30, 50, 20점이라고 할 때

조작한 점수는 30/50*100, 50/50*100 , 20/50*100 이다. 이때 조작한 점수의 값을 굳이 구하지 않아도 된다. 

조작한 점수의 평균을 구하는 식을 써보면,

(30/50*100 + 50/50*100 + 20/50*100)/3 이다. 

"/50*100"이 공통되었으므로 묶어보면 다음과 같다.

{(30+50+20) /50*100}/3 

순서를 조금 바꿔보면

(30+50+20) /3 /50*100

앞에 주황색으로 표시된 부분은 현재 점수의 평균과 같다. 

따라서, 조작한 점수의 값을 굳이 구하지 않아도 조작한 점수의 평균을 구할 수 있다. 

현재 점수의 평균 / 50 *100 을 하면 된다. 

 

현재 점수의 최고점을 구하는 방법은 배열을 오름차순으로 정렬하면된다. 즉, 정렬한 후의 배열의 마지막 원소가 최고점이 된다. 오름차순으로 정렬하는 방법은 java.util.Arrays 클래스의 sort() 메소드를 사용하면 된다 .

 

score, score의 합, n의 값 모두 int형 변수이므로 int로 선언한다. 

하지만, 문제에서 소수점 이하의 값도 표시하라고 했으니, 평균을 계산할 때 소수점도 나오게 형변환을 해주면 된다. 

 

4. 링크

www.acmicpc.net/problem/1546

 

1546번: 평균

첫째 줄에 시험 본 과목의 개수 N이 주어진다. 이 값은 1000보다 작거나 같다. 둘째 줄에 세준이의 현재 성적이 주어진다. 이 값은 100보다 작거나 같은 음이 아닌 정수이고, 적어도 하나의 값은 0보

www.acmicpc.net

 

1. 문제

두 자연수 A와 B가 있을 때, A%B는 A를 B로 나눈 나머지 이다. 예를 들어, 7, 14, 27, 38을 3으로 나눈 나머지는 1, 2, 0, 2이다.

수 10개를 입력받은 뒤, 이를 42로 나눈 나머지를 구한다. 그 다음 서로 다른 값이 몇 개 있는지 출력하는 프로그램을 작성하시오.

 

2. 코드

import java.util.Scanner;
import java.util.HashSet;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        HashSet<Integer> hs = new HashSet<Integer>();
        
        for(int i=0;i<10;i++){
            int numA=sc.nextInt();
            hs.add(numA%42);
        }
        
        System.out.println(hs.size());
        sc.close();
    }
}

 

3. 풀이

 

HashSet이용하기 - 서로 다른 나머지의 개수를 세는 것 이므로 HashSet을 이용하면 중복된 값은 제외된 상태로 저장됨

 

 

※ HashSet

- 자바 Collection 중 Set의 파생클래스

- 중복원소를 허용하지 않음

- 순서 개념이 없음 (정렬을 하고 싶으면 리스트로 변환해야함)

 

 

4. 링크

www.acmicpc.net/problem/3052

 

3052번: 나머지

39, 40, 41, 42, 43, 44, 82, 83, 84, 85를 42로 나눈 나머지는 39, 40, 41, 0, 1, 2, 40, 41, 0, 1이다. 서로 다른 값은 모두 6개가 있다.

www.acmicpc.net

 

1. 문제

세 개의 자연수 A, B, C가 주어질 때 A×B×C를 계산한 결과에 0부터 9까지 각각의 숫자가 몇 번씩 쓰였는지를 구하는 프로그램을 작성하시오.

예를 들어 A = 150, B = 266, C = 427 이라면 

A × B × C = 150 × 266 × 427 = 17037300 이 되고, 

계산한 결과 17037300 에는 0이 3번, 1이 1번, 3이 2번, 7이 2번 쓰였다.

첫째 줄에는 A×B×C의 결과에 0 이 몇 번 쓰였는지 출력한다. 마찬가지로 둘째 줄부터 열 번째 줄까지 A×B×C의 결과에 1부터 9까지의 숫자가 각각 몇 번 쓰였는지 차례로 한 줄에 하나씩 출력한다.

 

2. 코드

import java.util.Scanner;
import java.util.stream.*;
import java.util.Arrays;
import java.lang.Math;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int a,b,c;
        int[] cnt = new int[10];
        a=sc.nextInt(); b=sc.nextInt(); c=sc.nextInt();
        int number = a*b*c;
        int length = (int)(Math.log10(a*b*c)+1);
        int[] digits = Stream.of(String.valueOf(number).split("")).mapToInt(Integer::parseInt).toArray();
        for(int i=0;i<length;i++){
            for(int j=0;j<10;j++){
                if(digits[i]==j)    cnt[j]++;
            }
        }
        for(int i=0;i<10;i++){
          System.out.println(cnt[i]);
        }
        sc.close();
    }
}

 

3. 풀이

 

숫자의 길이를 구하는 방법

int number = 12345;
int length = (int)(Math.log10(number)+1);
//double 형이 되므로 int형으로 형변환 시켜줘야 함

 

각 자리수를 배열에 저장하는 방법

// import java.util.Arrays;
// import java.util.stream.*;
int num = 12345;
int[] digits = Stream.of(String.valueOf(number).split("")).mapToInt(Integer::parseInt).toArray();

 

4. 링크

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

 

2577번: 숫자의 개수

첫째 줄에 A, 둘째 줄에 B, 셋째 줄에 C가 주어진다. A, B, C는 모두 100보다 같거나 크고, 1,000보다 작은 자연수이다.

www.acmicpc.net

 

+ Recent posts