문제

2017년에 이어, 2018년에도 카카오 코드 페스티벌이 개최된다!

카카오 코드 페스티벌에서 빠질 수 없는 것은 바로 상금이다. 2017년에 개최된 제1회 코드 페스티벌에서는, 본선 진출자 100명 중 21명에게 아래와 같은 기준으로 상금을 부여하였다.

순위 상금 인원
1등 500만원 1명
2등 300만원 2명
3등 200만원 3명
4등 50만원 4명
5등 30만원 5명
6등 10만원 6명

2018년에 개최될 제2회 코드 페스티벌에서는 상금의 규모가 확대되어, 본선 진출자 64명 중 31명에게 아래와 같은 기준으로 상금을 부여할 예정이다.

순위 상금 인원
1등 512만원 1명
2등 256만원 2명
3등 128만원 4명
4등 64만원 8명
5등 32만원 16명

제이지는 자신이 코드 페스티벌에 출전하여 받을 수 있을 상금이 얼마인지 궁금해졌다. 그는 자신이 두 번의 코드 페스티벌 본선 대회에서 얻을 수 있을 총 상금이 얼마인지 알아보기 위해, 상상력을 발휘하여 아래와 같은 가정을 하였다.

  • 제1회 코드 페스티벌 본선에 진출하여 a등(1 ≤ a ≤ 100)등을 하였다. 단, 진출하지 못했다면 a = 0으로 둔다.

  • 제2회 코드 페스티벌 본선에 진출하여 b등(1 ≤ b ≤ 64)등을 할 것이다. 단, 진출하지 못했다면 b = 0으로 둔다.

제이지는 이러한 가정에 따라, 자신이 받을 수 있는 총 상금이 얼마인지를 알고 싶어한다.

입력

첫 번째 줄에 제이지가 상상력을 발휘하여 가정한 횟수 T(1 ≤ T ≤ 1,000)가 주어진다.

다음 T개 줄에는 한 줄에 하나씩 제이지가 해본 가정에 대한 정보가 주어진다. 각 줄에는 두 개의 음이 아닌 정수 a(0 ≤ a ≤ 100)와 b(0 ≤ b ≤ 64)가 공백 하나를 사이로 두고 주어진다.

출력

각 가정이 성립할 때 제이지가 받을 상금을 원 단위의 정수로 한 줄에 하나씩 출력한다. 입력이 들어오는 순서대로 출력해야 한다.

예제 입력 1

6
8 4
13 19
8 10
18 18
8 25
13 16

예제 출력 1

1780000
620000
1140000
420000
820000
620000

더보기

Solution

#include<stdio.h>

int main(void)
{
	int T;

	scanf("%d", &T);

	for(int t=0;t<T;t++)
	{
		int a, b, price=0;

		scanf("%d %d", &a, &b);

		if(a==0 || a>21)
			price+=0;
		else if(a==1)
			price+=5000000;
		else if(a<4)
			price+=3000000;
		else if(a<7)
			price+=2000000;
		else if(a<11)
			price+=500000;
		else if(a<16)
			price+=300000;
		else
			price+=100000;

		if(b==0 || b>31)
			price+=0;
		else if(b==1)
			price+=5120000;
		else if(b<4)
			price+=2560000;
		else if(b<8)
			price+=1280000;
		else if(b<16)
			price+=640000;
		else
			price+=320000;

		printf("%d\n", price);
	}

	return 0;
}
728x90

문제

수학자가 구를 깎아서 볼록다면체를 만들었다. 이 수학자는 임의의 볼록다면체에 대해 (꼭짓점의 수) - (모서리의 수) + (면의 수) = 2가 성립한다는 것을 알고 있다. 그래서 구를 깎는 게 취미인 이 사람은 꼭짓점, 모서리와 면의 수를 기록할 때 꼭짓점과 모서리의 수만 세고 면의 수는 세지 않는다.

입력

첫 번째 줄에 1 이상 100 이하의 자연수 T가 주어진다.

다음 T개의 줄에 4 이상 100 이하의 자연수 V와 E가 공백을 사이에 두고 주어진다. V와 E는 각각 꼭짓점의 개수와 모서리의 개수이다.

출력

각 V와 E에 대해 볼록다면체의 면의 수를 한 줄에 하나씩 출력한다.

예제 입력 1

2
8 12
4 6

예제 출력 1

6
4

더보기

Solution

#include<stdio.h>

int main(void)
{
	int T;

	scanf("%d", &T);

	for(int t=0;t<T;t++)
	{
		int V, E;

		scanf("%d %d", &V, &E);

		printf("%d\n", 2-V+E);
	}

	return 0;
}
728x90

문제

KOI 통신연구소는 레이저를 이용한 새로운 비밀 통신 시스템 개발을 위한 실험을 하고 있다. 실험을 위하여 일직선 위에 N개의 높이가 서로 다른 탑을 수평 직선의 왼쪽부터 오른쪽 방향으로 차례로 세우고, 각 탑의 꼭대기에 레이저 송신기를 설치하였다. 모든 탑의 레이저 송신기는 레이저 신호를 지표면과 평행하게 수평 직선의 왼쪽 방향으로 발사하고, 탑의 기둥 모두에는 레이저 신호를 수신하는 장치가 설치되어 있다. 하나의 탑에서 발사된 레이저 신호는 가장 먼저 만나는 단 하나의 탑에서만 수신이 가능하다. 

예를 들어 높이가 6, 9, 5, 7, 4인 다섯 개의 탑이 수평 직선에 일렬로 서 있고, 모든 탑에서는 주어진 탑 순서의 반대 방향(왼쪽 방향)으로 동시에 레이저 신호를 발사한다고 하자. 그러면, 높이가 4인 다섯 번째 탑에서 발사한 레이저 신호는 높이가 7인 네 번째 탑이 수신을 하고, 높이가 7인 네 번째 탑의 신호는 높이가 9인 두 번째 탑이, 높이가 5인 세 번째 탑의 신호도 높이가 9인 두 번째 탑이 수신을 한다. 높이가 9인 두 번째 탑과 높이가 6인 첫 번째 탑이 보낸 레이저 신호는 어떤 탑에서도 수신을 하지 못한다.

탑들의 개수 N과 탑들의 높이가 주어질 때, 각각의 탑에서 발사한 레이저 신호를 어느 탑에서 수신하는지를 알아내는 프로그램을 작성하라. 

입력

첫째 줄에 탑의 수를 나타내는 정수 N이 주어진다. N은 1 이상 500,000 이하이다. 둘째 줄에는 N개의 탑들의 높이가 직선상에 놓인 순서대로 하나의 빈칸을 사이에 두고 주어진다. 탑들의 높이는 1 이상 100,000,000 이하의 정수이다.

출력

첫째 줄에 주어진 탑들의 순서대로 각각의 탑들에서 발사한 레이저 신호를 수신한 탑들의 번호를 하나의 빈칸을 사이에 두고 출력한다. 만약 레이저 신호를 수신하는 탑이 존재하지 않으면 0을 출력한다.

예제 입력 1

5
6 9 5 7 4

예제 출력 1

0 0 2 2 4

더보기

Solution

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
	int N, *top=NULL, *signal=NULL;

	scanf("%d", &N);
	top=(int *)malloc(N*sizeof(int));
	signal=(int *)calloc(N,sizeof(int));

	for(int n=0;n<N;n++)
		scanf("%d", &top[n]);

	for(int i=1;i<N;i++)
		if(top[i]<top[i-1])
			signal[i]=i;
		else
		{
			int temp=i;

			while(temp>0)
			{
				temp=signal[temp-1];
				if(temp>0 && top[temp-1]>top[i])
				{
					signal[i]=temp;
					break;
				}
			}
		}

	for(int n=0;n<N;n++)
		printf("%d ", signal[n]);
	printf("\n");
	free(signal);
	free(top);
	return 0;
}
더보기

Solution

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb=new StringBuilder();
		StringTokenizer st;
		
		int N=Integer.parseInt(br.readLine());
		int[] top=new int[N], signal=new int[N];
		
		st=new StringTokenizer(br.readLine());
		for(int i=0;i<N;i++)
			top[i]=Integer.parseInt(st.nextToken());

		for(int i=1;i<N;i++)
			if(top[i]<top[i-1])
				signal[i]=i;
			else {
				int temp=i;
				
				while(temp>0) {
					temp=signal[temp-1];

					if(temp>0 && top[temp-1]>top[i]) {
						signal[i]=temp;
						break;
					}
				}
			}
		
		for(int i=0;i<N;i++)
			sb.append(signal[i]+" ");
		
		System.out.println(sb.toString());
	}
}

 

728x90

문제

여덟 자리의 양의 정수가 주어질 때, 그 안에서 연속하여 같은 숫자가 나오는 것이 없으면 1을 출력하고, 있으면 같은 숫자가 연속해서 나오는 구간 중 가장 긴 것의 길이를 출력하는 프로그램을 작성하라. 

예를 들어 세 개의 숫자 12345123, 17772345, 22233331이 주어졌다고 하자. 12345123은 연속하여 같은 숫자가 나오는 것이 없으므로 1을 출력하고, 17772345는 7이 세 개 연속하여 나오므로 3을 출력하며, 22233331의 경우에는 2가 세 개, 3이 네 개 연속해서 나오므로 그 중 큰 값인 4를 출력하여야 한다.  

입력

첫째 줄부터 셋째 줄까지 각 줄에 하나씩 세 개의 여덟 자리 양의 정수가 주어진다.

출력

첫째 줄에서 셋째 줄까지 한 줄에 하나씩 각 입력된  수 내에서 같은 숫자가 연속하여 나오는 가장 긴 길이를 입력 순서대로 출력한다.

예제 입력 1

12345123
17772345
22233331

예제 출력 1

1
3
4

더보기

Solution

#include<stdio.h>

int main(void)
{
	for(int t=0;t<3;t++)
	{
		int arr[8], length=1, max=1;

		for(int i=0;i<8;i++)
			scanf("%1d", &arr[i]);
		for(int i=1;i<8;i++)
		{
			length=arr[i]==arr[i-1]?length+1:1;
			max=length>max?length:max;
		}

		printf("%d\n", max);
	}

	return 0;
}
728x90

문제

동수는 제과점에 과자를 사러 가는데 현재 가진 돈이 모자랄 경우 부모님께 모자란 돈을 받으려고 한다. 과자 한 개의 가격이 K, 사려고 하는 과자의 개수가 N이고, 현재 가진 돈의 액수를 M이라 할 때 여러분은 동수가 부모님께 받아야 하는 모자란 돈을 계산하려고 한다. 

예를 들어, 과자 한 개의 가격이 30원, 사려고 하는 과자의 개수가 4개, 현재 동수가 가진 돈이 100원이라 할 때, 동수가 부모님께 받아야 하는 돈은 20원이다. 과자 한 개의 가격이 250원, 사려고 하는 과자의 개수가 2개, 현재 동수가 가진 돈이 140원이라 할 때, 동수가 부모님께 받아야 하는 돈은 360원이다. 과자 한 개의 가격이 20원, 사려고 하는 과자의 개수가 6개, 현재 동수가 가진 돈이 120원이라 할 때 동수가 부모님께 받아야 하는 돈은 0원이다. 과자 한 개의 가격이 20원, 사려고 하는 과자의 개수가 10개, 현재 동수가 가진 돈이 320원이라 할 때 동수가 부모님께 받아야 하는 돈은 역시 0원이다. 

과자 한 개의 가격, 사려고 하는 과자의 개수와 동수가 현재 가진 돈의 액수가 주어질 때 동수가 부모님께 받아야 하는 돈의 액수를 출력하는 프로그램을 작성하시오. 

입력

첫 번째 줄에는 과자 한 개의 가격 K, 사려고 하는 과자의 개수 N, 현재 동수가 가진 돈 M이 각각 공백을 사이에 두고 주어진다. 단, K, N은 1,000 이하의 양의 정수이고, M은 10만 이하의 양의 정수이다. (1 ≤ K, N ≤ 1,000, 1 ≤ M ≤ 100,000이다.) 

출력

첫 줄에 동수가 부모님께 받아야 하는 돈의 액수를 출력한다. 

예제 입력 1

300 4 1000

예제 출력 1

200

더보기

Solution

#include<stdio.h>

int main(void)
{
	int K, N, M;

	scanf("%d %d %d", &K, &N, &M);

	printf("%d\n", K*N>=M?K*N-M:0);

	return 0;
}
728x90

문제

카지노에서 제일 인기 있는 게임 블랙잭의 규칙은 상당히 쉽다. 카드의 합이 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장의 합을 출력한다.

예제 입력 1

5 21
5 6 7 8 9

예제 출력 1

21

예제 입력 2

10 500
93 181 245 214 315 36 185 138 216 295

예제 출력 2

497

더보기

Solution

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
	int N, M, current=0, *card=NULL;

	scanf("%d %d", &N, &M);
	card=(int *)malloc(N*sizeof(int));

	for(int i=0;i<N;i++)
		scanf("%d", &card[i]);

	for(int i=0;i<N-2;i++)
		for(int j=i+1;j<N-1;j++)
			for(int k=j+1;k<N;k++)
				if(card[i]+card[j]+card[k]<=M && card[i]+card[j]+card[k]>current)
					current=card[i]+card[j]+card[k];

	printf("%d\n", current);

	free(card);
	return 0;
}
728x90

문제

가로, 세로의 크기가 각각 100인 정사각형 모양의 흰색 도화지가 있다. 이 도화지 위에 가로, 세로의 크기가 각각 10인 정사각형 모양의 검은색 색종이를 색종이의 변과 도화지의 변이 평행하도록 붙인다. 이러한 방식으로 색종이를 한 장 또는 여러 장 붙인 후 색종이가 붙은 검은 영역의 넓이를 구하는 프로그램을 작성하시오.

예를 들어 흰색 도화지 위에 세 장의 검은색 색종이를 그림과 같은 모양으로 붙였다면 검은색 영역의 넓이는 260이 된다.

입력

첫째 줄에 색종이의 수가 주어진다. 이어 둘째 줄부터 한 줄에 하나씩 색종이를 붙인 위치가 주어진다. 색종이를 붙인 위치는 두 개의 자연수로 주어지는데 첫 번째 자연수는 색종이의 왼쪽 변과 도화지의 왼쪽 변 사이의 거리이고, 두 번째 자연수는 색종이의 아래쪽 변과 도화지의 아래쪽 변 사이의 거리이다. 색종이의 수는 100 이하이며, 색종이가 도화지 밖으로 나가는 경우는 없다

출력

첫째 줄에 색종이가 붙은 검은 영역의 넓이를 출력한다.

예제 입력 1

3
3 7
15 7
5 2

예제 출력 1

260

더보기

Solution

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>

int main(void)
{
	int N, area=0;
	bool **paper=NULL;

	paper=(bool **)malloc(100*sizeof(bool *));
	for(int i=0;i<100;i++)
		paper[i]=(bool *)calloc(100,sizeof(bool));

	scanf("%d", &N);

	for(int i=0;i<N;i++)
	{
		int X, Y;

		scanf("%d %d", &X, &Y);

		for(int x=X;x<X+10;x++)
			for(int y=Y;y<Y+10;y++)
				paper[x][y]=true;
	}

	for(int x=0;x<100;x++)
		for(int y=0;y<100;y++)
			area+=paper[x][y];

	printf("%d\n", area);

	for(int i=0;i<100;i++)
		free(paper[i]);
	free(paper);
	return 0;
}
728x90

문제

창영이는 노래 여러 개를 이어서 부르는 가수이다. 유명한 노래의 비슷한 멜로디를 이어서 부르면서 언제 곡이 넘어갔는지 모르게 만드는 것이 창영이 노래의 특징이다. 이런 노래로 상업적으로 엄청난 성공을 거둔 창영이에게 큰 시련이 찾아왔다. 그것은 바로 저작권이었다.

창영이의 노래에 포함되어 있는 멜로디는 모두 저작권이 다른 사람에게 있는 노래이다. 따라서, 이 음악으로 상업적인 활동을 했기 때문에, 저작권 협회에 저작권료를 내야한다.

창영이는 자신의 앨범에 포함되어있는 저작권이 있는 멜로디의 평균값을 구해보기로 했다. 이 값은 아래와 같이 구할 수 있다.

(창영이 앨범에 수록된 곡에 포함되어 있는 저작권이 있는 멜로디의 개수) / (앨범에 수록된 곡의 개수)

이때, 평균값은 항상 올림을 해서 정수로 만들어야 한다. 예를 들어, 창영이의 1집 앨범 "영창에서 영원히 영창피아노를 친다"에 총 38개 곡이 수록되어 있고, 이 앨범에 저작권이 있는 멜로디가 894개가 있다면, 평균값은 23.53이 되고 올림해서 24가 된다.

매니저 강산이는 얼마나 많은 사람에게 저작권료를 주어야 하는지 궁금해졌다. 강산이가 알고 있는 정보는 앨범에 수록되어 있는 곡의 개수와 위에서 구한 평균값이다. 이때, 적어도 몇 곡이 저작권이 있는 멜로디인지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 앨범에 수록된 곡의 개수 A와 평균값 I가 주어진다. (1 ≤ A, I ≤ 100)

출력

첫째 줄에 적어도 몇 곡이 저작권이 있는 멜로디인지 출력한다.

예제 입력 1

38 24

예제 출력 1

875

더보기

Solution

#include<stdio.h>

int main(void)
{
	int A, I;

	scanf("%d %d", &A, &I);

	printf("%d\n", A*(I-1)+1);

	return 0;
}
728x90

+ Recent posts