반응형

안녕하세요!

 

오늘은 Springboot 프로젝트를 Jar파일로 만들고, 실행하는 것까지 순서대로 알려드리겠습니다.

 

스프링부트 프로젝트를 JAR 파일로 만들어 배포하는 과정은 다음과 같습니다.

1. IntelliJ에서 프로젝트를 빌드합니다.

  • IntelliJ에서 Maven 또는 Gradle을 사용하여 프로젝트를 빌드합니다.
  • 빌드를 수행하면 프로젝트의 소스 코드가 컴파일되고, 라이브러리 의존성이 해결됩니다.

2. JAR 파일 생성 설정 확인

  • 스프링부트는 기본적으로 JAR 파일로 패키징됩니다. JAR 파일 생성 설정이 되어 있는지 확인합니다.
  • 만약 설정이 되어있지 않다면, pom.xml 파일에 다음과 같이 설정합니다.
<build>
   <plugins>
      <plugin>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
   </plugins>
</build>
 

3. JAR 파일 빌드

  • IntelliJ에서 Maven 탭을 열고 clean과 package를 차례로 실행합니다.
  • 또는 터미널에서 mvn clean package 명령어를 실행합니다.
  • 빌드가 완료되면 target 폴더에 JAR 파일이 생성됩니다.

4. JAR 파일 실행 확인

  • 생성된 JAR 파일을 실행하여 정상적으로 작동하는지 확인합니다.
  • 터미널에서 java -jar <파일명>.jar 명령어를 실행합니다.

위까지의 과정이 헷갈리신다면, 아래 제가 작성한 다른 글을 한번 보고 오시면 쉽게 이해되실거에요!

https://chunghyup.tistory.com/79

 

IntelliJ 프로젝트를 Jar 로 만들어서 배포하기

안녕하세요. 저번 게시물에서는 IntelliJ에서 Hello world 프로젝트를 만들었죠? https://chunghyup.tistory.com/78 intellij 자바 프로젝트 만들어서 Hello world 실행하기 안녕하세요. 이번에 간단한 스크립트를 짜

chunghyup.tistory.com

 

5. JAR 파일 배포

  • 생성된 JAR 파일을 배포하고자 하는 서버에 복사합니다.
  • 배포된 서버에서 java -jar <파일명>.jar 명령어를 실행하여 서버가 정상적으로 구동되는지 확인합니다.

위의 과정을 따르면 스프링부트 프로젝트를 JAR 파일로 만들어 배포할 수 있습니다.

반응형
반응형

문제

4 × 3 = 12이다.

이 식을 통해 다음과 같은 사실을 알 수 있다.

3은 12의 약수이고, 12는 3의 배수이다.

4도 12의 약수이고, 12는 4의 배수이다.

두 수가 주어졌을 때, 다음 3가지 중 어떤 관계인지 구하는 프로그램을 작성하시오.

  1. 첫 번째 숫자가 두 번째 숫자의 약수이다.
  2. 첫 번째 숫자가 두 번째 숫자의 배수이다.
  3. 첫 번째 숫자가 두 번째 숫자의 약수와 배수 모두 아니다.

입력

입력은 여러 테스트 케이스로 이루어져 있다. 각 테스트 케이스는 10,000이 넘지않는 두 자연수로 이루어져 있다. 마지막 줄에는 0이 2개 주어진다. 두 수가 같은 경우는 없다.

출력

각 테스트 케이스마다 첫 번째 숫자가 두 번째 숫자의 약수라면 factor를, 배수라면 multiple을, 둘 다 아니라면 neither를 출력한다.

반응형

해설

isFactor 함수와 isMultiple 함수 두가지만 만들면 쉽게 풀 수 있다.

쉬운 문제인 만큼 해설만 있으면 충분할듯

코드

// const dataFile = './data';
const dataFile = '/dev/stdin';
const fs = require('fs');
const inputs = fs.readFileSync(dataFile).toString().split('\n').map(el => el.split(" ").map(el => parseInt(el)));

const run = (inputs) => {
  let i = 0;
  while(true) {
    const input = inputs[i]
    if(isLast(input)) { break; } 
    if(isFactor(input)) {
      console.log("factor")
    } else if (isMultiple(input)) {
      console.log("multiple")
    } else {
      console.log("neither")
    }
    i++;
  }
}

const isLast = (input) => {
  return input[0] == 0 && input[1] == 0;
}

const isFactor = (input) => {
  if(input[0] >= input[1]) {
    return false;
  }

  return input[1]%input[0] == 0
}

const isMultiple = (input) => {
  if(input[1] >= input[0]) {
    return false;
  }

  return input[0]%input[1] == 0
}
run(inputs);
반응형
반응형

정렬 알고리즘 중 삽입 정렬(Insertion sort)에 대해서 설명을 드리고, 백준 알고리즘에서 실전 문제를 푸는 것 까지 진행을 해볼게요.

 

삽입 정렬은 정렬 알고리즘을 처음 접하시는 분들도 매우 직관적으로 이해 할 수 있는 알고리즘 입니다.

 

매우 간단한 알고리즘인데요.

 

간단하게 설명을 드리면

삽입 정렬은 배열의 모든 요소를 하나씩 비교하면서,
비어있는 배열에 하나씩 옮기는 방식의 알고리즘 입니다.
이 옮기는 과정에서 정렬이 되도록 삽입 해줍니다.

즉, 올바른 위치에 계속해서 삽입(Insertion) 만 해준다면 우리는 정렬이 된 배열을 얻을 수 있습니다.

 

그림으로 설명해 드릴게요.

 

저희는 3, 1, 7 3개의 숫자가 있는 배열을 가지고 있고,

이 배열을 정렬을 하고 싶습니다.

오름차순으로 정렬을 하여 1, 3, 7 배열을 얻고 싶은거죠.

 

위에 설명대로 첫번째 3을 비어있는 배열에 옮기겠습니다.

 

첫번째 요소이고 옮길 곳은 배열이 비어있기 때문에 그냥 3을 옮겨놓습니다.

 

다음으로 1을 옮겨야 하는데요.

 

이미 3보다 큰 3이 배열에 들어가 있기 때문에

1은 3보다 앞에 삽입(Insertion) 되어야 합니다.

 

3을 한칸 뒤로 밀고 1을 넣으면 아래처럼 됩니다.

 

마지막으로 7을 넣어야 하는데,

복사본 배열과 비교를 해보니 모든 숫자가 7보다 작네요.

그럼 제일 끝에 삽입을 하면 되겠네요.

 

이렇게 정렬이 완료 되었습니다.

 

백준에서 관련 문제를 찾아보겠습니다.

 

많은 정렬 문제가 있지만, 삽입 정렬은 O(n^2)의 방법이기 때문에 시간제약이 적은 문제를 가서 풀어야합니다.

 

백준에서는 2750번: 수 정렬하기 문제에서 연습해보실 수 있습니다.

 

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

 

2750번: 수 정렬하기

첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수 주어진다. 이 수는 절댓값이 1,000보다 작거나 같은 정수이다. 수는 중복되지 않는다.

www.acmicpc.net

 

해설

저는 문제를 풀기에 앞서서 함수를 먼저 작성하였는데요.

 

정렬을 위한 Sort라는 함수를 작성하였고.

 

삽입정렬에서의 삽입 이라는 기능을 위한 insert라는 함수를 정의하였습니다.

 

Sort 함수에서는 기존 배열의 요소들을 하나씩 insert 함수를 사용하여 정렬을 하고,

 

insert 함수는 각 요소가 들어갈 위치를 찾고 삽입하는 역할을 수행합니다.

 

코드

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().split('\n');
const N = parseInt(input[0]);
 
const list = [];
for(let i = 1; i <= N; i++) {
  list.push(parseInt(input[i]));
}
 
// sort 함수 구현
function sort(unsortedList) {
  const sortedList = []
  for(let num of unsortedList) {
    insert(sortedList, num)
  }
  return sortedList;
}
 
// 삽입 함수 구현
function insert(sortedList, num) {
  let index = -1;
  for(let i = 0; i < sortedList.length; i++) {
    if(sortedList[i] < num) {
      continue;
    } else {
      index = i;
      break;
    }
  }
 
  if(index < 0) {
    sortedList.push(num);
  } else {
    sortedList = sortedList.splice(index, 0, num);
  }
}
 
let sortedList = sort(list);
 
for(let num of sortedList) {
  console.log(num);
}
cs
반응형
반응형

안녕하세요.

 

저번 게시물에서는 IntelliJ에서 Hello world 프로젝트를 만들었죠?

https://chunghyup.tistory.com/78

 

intellij 자바 프로젝트 만들어서 Hello world 실행하기

안녕하세요. 이번에 간단한 스크립트를 짜는데, 하필 DB가 Tibero db라서 자바를 이용해서 스크립트를 짜게 되었습니다. Odbc를 사용할수도 있지만, 윈도우 환경이 아니면 Tibero Odbc가 잘 동작하지가

chunghyup.tistory.com

 

이번에는 이 프로젝트를 Jar로 만들어서 실행하는 방법을 알려드리려고 합니다.

 

저같은 경우에는 Java를 이용해서 간단하게 만든 프로그램을

 

Cron을 이용해서 실행시키거나, 일회용 스크립트와 같은 자바 프로그램을 실행할때 jar를 이용한 배포를 사용합니다.

 

순서대로 진행해볼게요.

 

상단에 있는 File 을 눌러보시면 Project Structure 라는 메뉴가 보이는데요.

이 메뉴로 이동을 해주세요.

 

그럼 아래와 같은 창이 뜹니다.

좌측에 Artifacts라는 메뉴를 눌러 주시면, 현재는 텅 비어있는데요.

상단에 보이는 + 버튼을 눌러서 Artifact를 추가해 줄 예정입니다.

 

+를 눌러주세요.

 

제일 상단에 보이는 JAR를 선택하고, 프로젝트에 포함된 모든 의존성을 함께 빌드하기 위해서

From modules with dependencies를 선택해주세요.

 

다음과 같은 모달 창이 뜹니다.

여기서 Main Class를 선택해주시면 됩니다.

이전 게시물에서 오신 분이라면, template 을 선택했기 때문에 저와 같은 Main 클래스가 있을텐데요.

아래 이미지와 같이 그 Main class를 선택해주세요.

 

 

Main클래스를 선택해주시면 준비는 끝났습니다.

OK를 눌러서 Artifact가 아래와 같이 추가가 되었는지 확인해주세요.

위 이미지와 같이 추가가 되었으면 마지막으로 OK를 누르면 Jar를 만들기 위한 준비는 끝이납니다.

이제 Jar 파일을 만들고 실행해 볼까요?

상단에 Build 메뉴에서 Build Artifacts로 이동을 해주세요.

(조금전에 Artifact를 만들었죠?)

 

아래와 같이 작은 팝업창 같은게 뜨면, 저희가 만들었던 java:jar Artifact를 선택하고 build 를 눌러주세요.

빌드를 누르면 out 디렉토리 안에 위와같이 jar 파일이 생기는 것을 확인 할 수 있어요.

이제 실행만 하면 됩니다.

 

실행을 위한 명령어는

 

java -jar  파일명

 

입니다.

끝!!

이제 jar 배포도 하실 수 있겠죠?

 

반응형
반응형

안녕하세요.

 

이번에 간단한 스크립트를 짜는데,

 

하필 DB가 Tibero db라서 자바를 이용해서 스크립트를 짜게 되었습니다.

 

Odbc를 사용할수도 있지만, 윈도우 환경이 아니면 Tibero Odbc가 잘 동작하지가 않더라고요.

 

그래서 local 환경에서 Java로 스크립트를 작성하고, CentOs 환경으로 Jar파일을 옮겨 실행을 했는데요.

 

순서대로 IntelliJ에서 Java 프로젝트를 만들어서 Jar 파일을 만들고 실행하는것 까지 진행해보겠습니다.

 

IntelliJ에서 Create New Project를 선택해주세요.

 

저희는 기본 자바 프로젝트를 만들것이기 때문에 Java를 선택해주시고요.

이번에 진행하는 부분에서는 추가할 라이브러리나 프레임워크가 없기 때문에 Next를 눌러주세요.

 

다름에는 Template를 선택하는 화면이 나오는데요.

Command Line App을 선택하시면

public static void main(String[] args) 를 포함하는 Main 클래스를 자동으로 생성해주기 때문에

선택을 하고 Next로 진행해줄게요.

 

프로젝트 이름도 설정을 해주세요.

 

템플릿을 선택했기 때문에 기본적으로 Main 클래스가 생성이 되어 있고요,

친절하게 주석으로

write your code here 라고 적혀있네요.

여기에 Hello world를 출력하는 코드를 입력해보겠습니다.

 

Java에서는 System.out.println();  을 이용해서 표준입출력에 줄바꿈이 포함된 스트링을 출력 할 수 있어요.

 

여기까지 진행이 되었으면 코드는 완성되었습니다.

우측 상단에 보이는 run 버튼을 누르거나,

 

Ctrl+r을 이용해서 코드를 실행시켜 주세요.

 

하단에 Hello world가 정상적으로 출력이 되었죠?!

 

다음에는 이 프로젝트를 Jar로 묶어서 배포하는 방법을 알아보겠습니다.

 

감사합니다.

 

Jar 배포는 여기로 이동해주세요!

https://chunghyup.tistory.com/79

 

IntelliJ 프로젝트를 Jar 로 만들어서 배포하기

안녕하세요. 저번 게시물에서는 IntelliJ에서 Hello world 프로젝트를 만들었죠? https://chunghyup.tistory.com/78 intellij 자바 프로젝트 만들어서 Hello world 실행하기 안녕하세요. 이번에 간단한 스크립트를..

chunghyup.tistory.com

 

반응형
반응형

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

 

1436번: 영화감독 숌

666은 종말을 나타내는 숫자라고 한다. 따라서, 많은 블록버스터 영화에서는 666이 들어간 제목을 많이 사용한다. 영화감독 숌은 세상의 종말 이라는 시리즈 영화의 감독이다. 조지 루카스는 스타

www.acmicpc.net

문제

666은 종말을 나타내는 숫자라고 한다. 따라서, 많은 블록버스터 영화에서는 666이 들어간 제목을 많이 사용한다. 영화감독 숌은 세상의 종말 이라는 시리즈 영화의 감독이다. 조지 루카스는 스타워즈를 만들 때, 스타워즈 1, 스타워즈 2, 스타워즈 3, 스타워즈 4, 스타워즈 5, 스타워즈 6과 같이 이름을 지었고, 피터 잭슨은 반지의 제왕을 만들 때, 반지의 제왕 1, 반지의 제왕 2, 반지의 제왕 3과 같이 영화 제목을 지었다.

하지만 숌은 자신이 조지 루카스와 피터 잭슨을 뛰어넘는다는 것을 보여주기 위해서 영화 제목을 좀 다르게 만들기로 했다.

종말의 숫자란 어떤 수에 6이 적어도 3개이상 연속으로 들어가는 수를 말한다. 제일 작은 종말의 숫자는 666이고, 그 다음으로 큰 수는 1666, 2666, 3666, .... 과 같다.

따라서, 숌은 첫 번째 영화의 제목은 세상의 종말 666, 두 번째 영화의 제목은 세상의 종말 1666 이렇게 이름을 지을 것이다. 일반화해서 생각하면, N번째 영화의 제목은 세상의 종말 (N번째로 작은 종말의 숫자) 와 같다.

숌이 만든 N번째 영화의 제목에 들어간 숫자를 출력하는 프로그램을 작성하시오. 숌은 이 시리즈를 항상 차례대로 만들고, 다른 영화는 만들지 않는다.

입력

첫째 줄에 숫자 N이 주어진다. N은 10,000보다 작거나 같은 자연수이다.

출력

첫째 줄에 N번째 영화의 제목에 들어간 수를 출력한다.

 

해설

브루트포스 문제이기 때문에 "1부터 쭉 진행하며 N번째 숫자를 찾으면 된다" 라는 접근으로 문제를 해결하였다.

 

첫번째로 작성한 코드는 isEndNumber라는 함수로 input 숫자가 종말의 숫자인지(666을 포함하는 숫자인지) boolean의 output을 내는 참수를 작성하였다.

 

해당 함수는 숫자를 스트링으로 변환 후 6이 연속 3번 나오면 true를 반환하도록 하였다.

 

이후 1부터 진행하며 N번대 EndNumber를 찾아 stdout으로 출력하면 끝난다.

 

코드

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString()
const n = parseInt(input);
 
function isEndNumber(num) {
  const str = String(num);
  let count = 0;
  for(let i = 0; i < str.length; i++) {
    const char = str[i];
    if(char === '6') {
      count++;
    } else {
      count = 0;
    }
 
    if(count >= 3) {
      return true;
    }
  }
 
  return false;
}
 
let currentNum = 1;
let count = 0;
while(true) {
  if(isEndNumber(currentNum)) {
    count++;
    if(count === n) {
      console.log(currentNum);
      break;
    }
  }
  currentNum++;
}
cs
반응형
반응형

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

 

1018번: 체스판 다시 칠하기

첫째 줄에 N과 M이 주어진다. N과 M은 8보다 크거나 같고, 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에는 보드의 각 행의 상태가 주어진다. B는 검은색이며, W는 흰색이다.

www.acmicpc.net

문제

지민이는 자신의 저택에서 MN개의 단위 정사각형으로 나누어져 있는 M*N 크기의 보드를 찾았다. 어떤 정사각형은 검은색으로 칠해져 있고, 나머지는 흰색으로 칠해져 있다. 지민이는 이 보드를 잘라서 8*8 크기의 체스판으로 만들려고 한다.

체스판은 검은색과 흰색이 번갈아서 칠해져 있어야 한다. 구체적으로, 각 칸이 검은색과 흰색 중 하나로 색칠되어 있고, 변을 공유하는 두 개의 사각형은 다른 색으로 칠해져 있어야 한다. 따라서 이 정의를 따르면 체스판을 색칠하는 경우는 두 가지뿐이다. 하나는 맨 왼쪽 위 칸이 흰색인 경우, 하나는 검은색인 경우이다.

보드가 체스판처럼 칠해져 있다는 보장이 없어서, 지민이는 8*8 크기의 체스판으로 잘라낸 후에 몇 개의 정사각형을 다시 칠해야겠다고 생각했다. 당연히 8*8 크기는 아무데서나 골라도 된다. 지민이가 다시 칠해야 하는 정사각형의 최소 개수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 N과 M이 주어진다. N과 M은 8보다 크거나 같고, 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에는 보드의 각 행의 상태가 주어진다. B는 검은색이며, W는 흰색이다.

출력

첫째 줄에 지민이가 다시 칠해야 하는 정사각형 개수의 최솟값을 출력한다.

 

해설

사실 부르트포스에 해설이랄게 뭐 있을까요? ㅠㅠ

하나하나 다 숫자를 세보면 됩니다!

 

저 같은 경우에는 첫번째 칸이 'B' 또는 'W'로 시작하고, 8x8 크기의 체스판을 칠할때

몇번을 칠하면 원하는 색으로 시작하는 체스판이 완성이 되는지

count하는 함수를 작성했어요.

 

countNeedPating(startRowNum, startColNum, startColor) 함수를 작성했고,

인수로 시작하는 row, col, color을 받아서 8x8을 직접 칠해보면서, count를 해줬습니다.

 

여기서 한가지 집중했던 점은

 

8x8 체스판은 64번을 칠하면 완성이 되는데,

첫번째 칸이 'B'일때와 'W'일때의 색칠해야 하는 횟수를 합치면 64가 된다는 것입니다.

따라서 B나 W로 시작하는 경우의 색칠 횟수 한번만 구하면 나머지 경우도 계산이 됩니다.

 

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().split('\n');
 
// input을 미리 정리합니다.
const [height, width] = input[0].split(' ').map(el => parseInt(el))
const originBoard = []
for(let i = 1; i <= height; i++) {
  let row = input[i].split('')
  originBoard.push(row)
}
 
// 우리가 색칠 할 Size를 먼저 정의를 해주었습니다.
// 문제를 풀때 x, y 만 수정하면 작은 경우의 수부터 테스트를 진행 할 수 있거든요.
const SIZE = {x:8, y:8}
 
// 색칠 횟수를 count 하는 함수를 먼저 정의합니다.
// 시작하는 위치에서 부터 SIZE에서 정의한 만큼의 체스판을 색칠해봅니다.
function countNeedPainting(startRowNum, startColNum, startColor) {
  let nextColor = startColor;
  let count = 0;
  // i = row
  for(let i = startRowNum; i < startRowNum + SIZE.x; i++) {
    // j = column
    for(let j = startColNum; j < startColNum + SIZE.y; j++) {
      if(originBoard[i][j] !== nextColor) {
        count++;
      }
      nextColor = nextColor === 'B' ? 'W' : 'B'
    }
    nextColor = nextColor === 'B' ? 'W' : 'B'
  }
  return count;
}
 
// 최소값을 미리 넉넉하게 설정해 뒀습니다.
let min = SIZE.x * SIZE.y;
// 전체 크기에서 체스판을 자를 수 있는 모든 경우의 수를 loop를 돌며 확인합니다.
for(let i = 0 ; i <= height - SIZE.x; i++) {
  for(let j = 0; j <= width - SIZE.y; j++) {
    const blakCount = countNeedPainting(i, j, 'B');
    const whiteCount = (SIZE.x * SIZE.y) - blakCount;
    const currentMin = blakCount > whiteCount ? whiteCount : blakCount
 
    if(min > currentMin) {
      min = currentMin
    }
  }
}
 
console.log(min)
cs
반응형
반응형

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

 

7568번: 덩치

우리는 사람의 덩치를 키와 몸무게, 이 두 개의 값으로 표현하여 그 등수를 매겨보려고 한다. 어떤 사람의 몸무게가 x kg이고 키가 y cm라면 이 사람의 덩치는 (x, y)로 표시된다. 두 사람 A 와 B의 덩

www.acmicpc.net

문제

우리는 사람의 덩치를 키와 몸무게, 이 두 개의 값으로 표현하여 그 등수를 매겨보려고 한다. 어떤 사람의 몸무게가 x kg이고 키가 y cm라면 이 사람의 덩치는 (x, y)로 표시된다. 두 사람 A 와 B의 덩치가 각각 (x, y), (p, q)라고 할 때 x > p 그리고 y > q 이라면 우리는 A의 덩치가 B의 덩치보다 "더 크다"고 말한다. 예를 들어 어떤 A, B 두 사람의 덩치가 각각 (56, 177), (45, 165) 라고 한다면 A의 덩치가 B보다 큰 셈이 된다. 그런데 서로 다른 덩치끼리 크기를 정할 수 없는 경우도 있다. 예를 들어 두 사람 C와 D의 덩치가 각각 (45, 181), (55, 173)이라면 몸무게는 D가 C보다 더 무겁고, 키는 C가 더 크므로, "덩치"로만 볼 때 C와 D는 누구도 상대방보다 더 크다고 말할 수 없다.

N명의 집단에서 각 사람의 덩치 등수는 자신보다 더 "큰 덩치"의 사람의 수로 정해진다. 만일 자신보다 더 큰 덩치의 사람이 k명이라면 그 사람의 덩치 등수는 k+1이 된다. 이렇게 등수를 결정하면 같은 덩치 등수를 가진 사람은 여러 명도 가능하다. 아래는 5명으로 이루어진 집단에서 각 사람의 덩치와 그 등수가 표시된 표이다.

이름(몸무게, 키)덩치 등수

A (55, 185) 2
B (58, 183) 2
C (88, 186) 1
D (60, 175) 2
E (46, 155) 5

위 표에서 C보다 더 큰 덩치의 사람이 없으므로 C는 1등이 된다. 그리고 A, B, D 각각의 덩치보다 큰 사람은 C뿐이므로 이들은 모두 2등이 된다. 그리고 E보다 큰 덩치는 A, B, C, D 이렇게 4명이므로 E의 덩치는 5등이 된다. 위 경우에 3등과 4등은 존재하지 않는다. 여러분은 학생 N명의 몸무게와 키가 담긴 입력을 읽어서 각 사람의 덩치 등수를 계산하여 출력해야 한다.

입력

첫 줄에는 전체 사람의 수 N이 주어진다. 그리고 이어지는 N개의 줄에는 각 사람의 몸무게와 키를 나타내는 양의 정수 x와 y가 하나의 공백을 두고 각각 나타난다.

출력

여러분은 입력에 나열된 사람의 덩치 등수를 구해서 그 순서대로 첫 줄에 출력해야 한다. 단, 각 덩치 등수는 공백문자로 분리되어야 한다.

 

해설

등수를 구하는 문제이기 때문에 정렬을 하고, 확실하지 않은 경우는 rank를 공동으로 부여하면 된다.

 

하지만 위 같은 방법으로 구현을 할 시에 귀찮다....

 

정렬(nLogn) + rank(n) 으로 구현이 가능하지만 n^2인 방법으로 문제를 풀었다.

 

문제를 푼 접근 방법은

 

"Rank는 결국 나보다 더치가 큰 사람의 숫자 + 1" 이다.

 

나보다 큰 사람이 없으면 rank가 1이 되고, 나보다 큰 사람이 9명이면 내 rank는 10이 된다.

 

다음 코드는 node를 이용하여 구현한 결과이다.

 

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().split('\n');
const num = parseInt(input[0]);
 
// Person class를 통해 문제를 풀어보겠습니다.
class Person {
  constructor(weight, height) {
    this.weight = weight;
    this.height = height;
    this.rank = 0;
  }
}
 
const people = []
 
// input 을 통해서 모든 사람의 정보를 people에 저장을 합니다.
for(let i = 1; i <= num; i++) {
  const [weight, height] = input[i].split(" ");
  const person = new Person(weight, height);
  people.push(person);
}
 
// 전체 사람 중에서 '나'보다 덩치가 큰 사람을 count 하고 +1을 하면 내 rank가 됩니다.
for(let i = 0; i < people.length; i++) {
  let currentPeople = people[i];
  const biggerPeople = people.filter(person => person.weight > currentPeople.weight && person.height > currentPeople.height);
  currentPeople.rank = biggerPeople.length + 1;
}
 
// 결과를 출력합니다.
for(let person of people) {
  console.log(person.rank);
}
cs
반응형
반응형

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

 

2231번: 분해합

어떤 자연수 N이 있을 때, 그 자연수 N의 분해합은 N과 N을 이루는 각 자리수의 합을 의미한다. 어떤 자연수 M의 분해합이 N인 경우, M을 N의 생성자라 한다. 예를 들어, 245의 분해합은 256(=245+2+4+5)이

www.acmicpc.net

문제

어떤 자연수 N이 있을 때, 그 자연수 N의 분해합은 N과 N을 이루는 각 자리수의 합을 의미한다. 어떤 자연수 M의 분해합이 N인 경우, M을 N의 생성자라 한다. 예를 들어, 245의 분해합은 256(=245+2+4+5)이 된다. 따라서 245는 256의 생성자가 된다. 물론, 어떤 자연수의 경우에는 생성자가 없을 수도 있다. 반대로, 생성자가 여러 개인 자연수도 있을 수 있다.

자연수 N이 주어졌을 때, N의 가장 작은 생성자를 구해내는 프로그램을 작성하시오.

입력

첫째 줄에 자연수 N(1 ≤ N ≤ 1,000,000)이 주어진다.

출력

첫째 줄에 답을 출력한다. 생성자가 없는 경우에는 0을 출력한다.

 

해설

문제에서 얻을 수 있는 힌트를 먼저 살펴보면

 

"가장 작은 생성자"

"없을 수도 있다"

 

두가지 정도를 찾을 수 있을것 같다.

 

분해합은 반드시 생성자보다 크기 때문에 0부터 시작하면서 하나씩 생성자가 될 수 있는지 확인을 하면서 진행하면 문제를 풀 수 있다.

 

0부터 시작하는 이유는 "가장 작은 생성자"를 찾는 문제이기 때문이다.

 

만약 "가장 큰 생성자"를 찾는 문제라면 N 부터 0까지 진행하면 된다.

 

쉬운 문제이기 때문에 설명은 코드 주석으로 적어 놓았다.

 

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString();
 
const N = parseInt(input)
 
let M = 0
for(let i = 0; i < N; i++) {
  //각 자리수와 후보값의 합을 구하기 위한 변수
  let sum = 0;
 
  // 0부터 시작하는 후보값
  const candidateValue = i;
 
  //각 자리수를 구하기 위해서 숫자를 string으로 변환하여 계산한다.
  const stringValue = candidateValue.toString()
 
  for(let j = 0; j < stringValue.length; j++) {
    sum += parseInt(stringValue[j])
  }
 
  sum += candidateValue;
 
  if(sum == N) {
    M = candidateValue
    break;
  }
}
 
console.log(M)
cs
반응형
반응형

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

 

2798번: 블랙잭

첫째 줄에 카드의 개수 N(3 ≤ N ≤ 100)과 M(10 ≤ M ≤ 300,000)이 주어진다. 둘째 줄에는 카드에 쓰여 있는 수가 주어지며, 이 값은 100,000을 넘지 않는 양의 정수이다. 합이 M을 넘지 않는 카드 3장

www.acmicpc.net

문제

카지노에서 제일 인기 있는 게임 블랙잭의 규칙은 상당히 쉽다. 카드의 합이 21을 넘지 않는 한도 내에서, 카드의 합을 최대한 크게 만드는 게임이다. 블랙잭은 카지노마다 다양한 규정이 있다.

한국 최고의 블랙잭 고수 김정인은 새로운 블랙잭 규칙을 만들어 상근, 창영이와 게임하려고 한다.

김정인 버전의 블랙잭에서 각 카드에는 양의 정수가 쓰여 있다. 그 다음, 딜러는 N장의 카드를 모두 숫자가 보이도록 바닥에 놓는다. 그런 후에 딜러는 숫자 M을 크게 외친다.

이제 플레이어는 제한된 시간 안에 N장의 카드 중에서 3장의 카드를 골라야 한다. 블랙잭 변형 게임이기 때문에, 플레이어가 고른 카드의 합은 M을 넘지 않으면서 M과 최대한 가깝게 만들어야 한다.

N장의 카드에 써져 있는 숫자가 주어졌을 때, M을 넘지 않으면서 M에 최대한 가까운 카드 3장의 합을 구해 출력하시오.

입력

첫째 줄에 카드의 개수 N(3 ≤ N ≤ 100)과 M(10 ≤ M ≤ 300,000)이 주어진다. 둘째 줄에는 카드에 쓰여 있는 수가 주어지며, 이 값은 100,000을 넘지 않는 양의 정수이다.

합이 M을 넘지 않는 카드 3장을 찾을 수 있는 경우만 입력으로 주어진다.

출력

첫째 줄에 M을 넘지 않으면서 M에 최대한 가까운 카드 3장의 합을 출력한다.

 

해설

브루트포스(Brute Force) 문제이다.

카드 세장을 뽑아야하기 때문에, 간단하게 3중 loop를 이용해서 문제를 풀수 있다.

다만 한가지 주의를 해야하는 점은, 

! 동일한 카드를 뽑을 수 없다

위 사항만 주의한다면 쉽게 문제를 풀 수 있다.

코드가 간단하기 때문에 자세한 설명은 코드 주석으로 달아놓았다.

 

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const fs = require('fs');
const inputs = fs.readFileSync('/dev/stdin').toString().split("\n")
 
const firstLine = inputs[0].split(" ")
const secondLine = inputs[1].split(" ").map(el => parseInt(el))
 
const N = parseInt(firstLine[0])
const M = parseInt(firstLine[1])
 
let max = 0
//3장의 카드를 골라야 하기 때문에 i, j, k 3개의 index를 써서 for loop을 돈다
for(let i = 0; i < N; i++) {
  for(let j = 0; j < N; j++) {
    for(let k = 0; k < N; k++) {
      // 동일한 카드를 선택 할 수는 없기 때문에 아래 조건의 경우 다음 loop로 넘어간다.
      if(i == j || i == k || j == k) {
        continue;
      }
 
      // 서로 다른 카드가 선택된 경우 M을 초과하지 않는 최대값인지 확인 후 저장한다.
      const sum = secondLine[i] + secondLine[j] + secondLine[k]
      if(sum > max && sum <= M) {
        max = sum
      }
 
      // 규칙에 맞는 숫자가 나온 경우에 더이상 계산을 할 필요가 없기 떄문에 종료한다.
      if(max == M) {
        break;
      }
    }
  }
}
 
console.log(max)
 
cs
반응형

+ Recent posts