문제

비어있는 공집합 S가 주어졌을 때, 아래 연산을 수행하는 프로그램을 작성하시오.

  • add x: S에 x를 추가한다. (1 ≤ x ≤ 20) S에 x가 이미 있는 경우에는 연산을 무시한다.
  • remove x: S에서 x를 제거한다. (1 ≤ x ≤ 20) S에 x가 없는 경우에는 연산을 무시한다.
  • check x: S에 x가 있으면 1을, 없으면 0을 출력한다. (1 ≤ x ≤ 20)
  • toggle x: S에 x가 있으면 x를 제거하고, 없으면 x를 추가한다. (1 ≤ x ≤ 20)
  • all: S를 {1, 2, ..., 20} 으로 바꾼다.
  • empty: S를 공집합으로 바꾼다. 

입력

첫째 줄에 수행해야 하는 연산의 수 M (1 ≤ M ≤ 3,000,000)이 주어진다.

둘째 줄부터 M개의 줄에 수행해야 하는 연산이 한 줄에 하나씩 주어진다.

출력

check 연산이 주어질때마다, 결과를 출력한다.

예제 입력 1

26
add 1
add 2
check 1
check 2
check 3
remove 2
check 1
check 2
toggle 3
check 1
check 2
check 3
check 4
all
check 10
check 20
toggle 10
remove 20
check 10
check 20
empty
check 1
toggle 1
check 1
toggle 1
check 1

예제 출력 1

1
1
0
1
0
1
0
1
0
1
1
0
0
0
1
0

더보기

Solution

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

int main(void)
{
	bool S[21]={false, };
	int M;

	scanf("%d", &M);
	getchar();

	for(int m=0;m<M;m++)
	{
		int x;
		char command[10]={'\0', };

		getchar();
		fgets(command,sizeof(command),stdin);

		switch(command[0])
		{
			case 'd':		//add
						x=isdigit(command[4])?10*(command[3]-'0')+command[4]-'0':command[3]-'0';
						S[x]=true;
						break;
			case 'e':		//remove
						x=isdigit(command[7])?10*(command[6]-'0')+command[7]-'0':command[6]-'0';
						S[x]=false;
						break;
			case 'h':		//check
						x=isdigit(command[6])?10*(command[5]-'0')+command[6]-'0':command[5]-'0';
						printf("%d\n", S[x]);
						break;
			case 'o':		//toggle
						x=isdigit(command[7])?10*(command[6]-'0')+command[7]-'0':command[6]-'0';
						S[x]=S[x]==true?false:true;
						break;
			case 'l':		//all
						for(x=1;x<21;x++)
							S[x]=true;
						break;
			case 'm':		//empty
						for(x=1;x<21;x++)
							S[x]=false;
						break;
		}
	}

	return 0;
}
728x90

문제

크기가 N인 수열 A가 주어졌을 때, 세준이는 인접한 두 원소의 차이를 이용해서 크기가 N-1인 수열 B를 만들 수 있다.

예를 들어, A = {5,6,3,9,-1} 이었을 때, B = {6-5, 3-6, 9-3, -1-9} = {1,-3,6,-10}이 된다. 다른 말로 B[i] = A[i+1]-A[i]가 된다.

수열 A가 주어졌을 때, 세준이가 위의 방법을 K번 했을 때 나오는 수열을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 수열의 크기 N과 K가 주어진다. N은 20보다 작거나 같은 자연수이고, K는 0보다 크거나 같고, N-1보다 작거나 같은 자연수이다. 둘째 줄에는 수열이 ‘,’로 구분되어 주어진다.

출력

첫째 줄에 K번 변형한 수열을 ‘,’로 구분하여 출력한다.

예제 입력 1

5 1
5,6,3,9,-1

예제 출력 1

1,-3,6,-10

더보기

Solution

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

int main(void)
{
	int N, K, *A=NULL;

	scanf("%d %d", &N, &K);
	A=(int *)malloc(N*sizeof(int));
	scanf("%d", &A[0]);
	for(int n=1;n<N;n++)
		scanf(",%d", &A[n]);

	for(int k=1;k<=K;k++)
	{
		int *B=malloc((N-k)*sizeof(int));

		for(int n=1;n<=N-k;n++)
			B[n-1]=A[n]-A[n-1];

		A=(int *)realloc(A,(N-k)*sizeof(int));
		for(int n=0;n<N-k;n++)
			A[n]=B[n];

		free(B);
	}

	printf("%d", A[0]);
	for(int n=1;n<N-K;n++)
		printf(",%d", A[n]);
	printf("\n");
	free(A);
	return 0;
}
728x90

문제

창영마을에서 정인이의 반란은 실패로 끝났다. (3028번)

테러리스트로 변신한 정인이는 창영마을에 경고를 하려고 한다.

사실 정인이는 창영마을에서 제일 착한사람이다. 따라서, 사람들을 다치지 않게하려고 한다.

유튜브에서 폭발에 대한 동영상을 찾아보다가, 그는 나트륨을 물에 던지면 폭발한다는 사실을 알게 되었다.

정인이는 창영마을의 중심을 지나는 "강산강" 근처에 숨어있다가, 나트륨을 위의 동영상처럼 물에 던질 것이다.

현재 시간과 정인이가 나트륨을 던질 시간이 주어졌을 때, 정인이가 얼마나 숨어있어야 하는지 구하는 프로그램을 작성하시오. (정인이는 적어도 1초를 기다리며, 많아야 24시간을 기다린다.)

입력

첫째 줄에 현재 시간이 hh:mm:ss 형식으로 주어진다. (시, 분, 초) hh는 0보다 크거나 같고, 23보다 작거나 같으며, 분과 초는 0보다 크거나 같고, 59보다 작거나 같다.

둘째 줄에는 나트륨을 던질 시간이 위와 같은 형식으로 주어진다.

출력

첫째 줄에 정인이가 기다려야 하는 시간을 입력과 같은 형식으로 출력한다.

예제 입력 1

20:00:00
04:00:00

예제 출력 1

08:00:00

더보기

Solution

#include<stdio.h>

int main(void)
{
	int time[2][3];

	for(int t=0;t<2;t++)
	{
		char str[9]={'\0', };

		scanf("%s", str);

		time[t][0]=10*(str[0]-'0')+str[1]-'0';
		time[t][1]=10*(str[3]-'0')+str[4]-'0';
		time[t][2]=10*(str[6]-'0')+str[7]-'0';
	}

	for(int t=0;t<3;t++)
		time[1][t]-=time[0][t];
	for(int t=2;t>0;t--)
		while(time[1][t]<0)
		{
			time[1][t-1]--;
			time[1][t]+=60;
		}
	while(time[1][0]<0)
		time[1][0]+=24;
	if(time[1][0]+time[1][1]+time[1][2]==0)
		time[1][0]=24;

	printf("%02d:%02d:%02d\n", time[1][0], time[1][1], time[1][2]);
	return 0;
}
728x90

문제

Eirik drinks a lot of Bingo Cola to help him program faster, and over the years he has burned many unnecessary calories walking all the way to the kitchen to get some. To avoid this he has just bought a small fridge, which is beautifully placed next to his computer. To make it match his fancy big-tower with all its blinking LEDs, it is necessary to style it a bit.

He has bought a weight sensor with a display and a small general purpose programmable chip, to put underneath the fridge. The idea is to make the display show how many litres of Bingo Cola there is in the fridge. To do this he must read a binary register in the sensor, and convert it to a decimal number to be displayed.

입력

The first line of input gives n ≤ 1000, the number of test cases. Then follow n lines with positive numbers represented as 24-bit binary strings (0s and 1s).

출력

For each number, output its decimal representation, without any leading zeros.

예제 입력 1

5
000000000000000000000001
000000000001010101010101
000000000000000000001010
101011001010101100101101
111111111111111111111111

예제 출력 1

1
5461
10
11316013
16777215

더보기

Solution

#include<stdio.h>

int main(void)
{
	int n;

	scanf("%d", &n);

	for(int i=0;i<n;i++)
	{
		int binary[24]={0, }, decimal=0;

		for(int b=0;b<24;b++)
			scanf("%1d", &binary[b]);

		for(int p=0, power=1;p<24;p++,power*=2)
			decimal+=power*binary[23-p];

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

	return 0;
}
728x90

문제

2015, 2016년에 이어 2017년에도 연세대학교 교내 프로그래밍 경시대회가 열린다.

택희, 영훈이, 남규는 열심히 문제를 만들었고, 이에 대한 보상으로 과사로부터 사탕 N개를 받았다.

N개의 사탕을 적절히 나눠 가지기 위해 토론한 결과, 아래와 같은 방식으로 사탕을 나누기로 결정하였다.

  • 남는 사탕은 없어야 한다.
  • 남규는 영훈이보다 2개 이상 많은 사탕을 가져야 한다.
  • 셋 중 사탕을 0개 받는 사람은 없어야 한다.
  • 택희가 받는 사탕의 수는 홀수개가 되어서는 안 된다.

이제 사탕을 적절히 나누어 집에 돌아가던 중, 택희는 위와 같은 규칙을 만족하도록 세 명에게 사탕을 나누어 주는 방법의 수가 궁금해졌다.

사탕의 개수 N이 주어지면, 사탕을 세 사람에게 분배하는 서로 다른 경우의 수를 세 보자.

입력

첫째 줄에 사탕의 총 개수 N이 주어진다. (1 ≤ N ≤ 100)

출력

규칙에 맞게 사탕을 분배하는 경우의 수를 출력한다. 택희, 영훈이, 남규가 받은 사탕의 수를 각각 A, B, C개라고 할 때, 서로 다른 (A, B, C) 순서쌍의 수를 세면 된다.

만일 규칙에 맞게 사탕을 분배하는 방법이 없다면 0을 출력한다.

예제 입력 1

6

예제 출력 1

1

힌트

택희에게 2개, 영훈이에게 1개, 남규에게 3개를 주는 방법 하나뿐이다.


더보기

Solution

#include<stdio.h>

int main(void)
{
	int N, count=0;

	scanf("%d", &N);

	for(int th=2;th+4<=N;th+=2)
		for(int yh=1;2*yh+2+th<=N;yh++)
			count+=N-th-yh>=yh+2;

	printf("%d\n", count);
	return 0;
}
728x90

문제

  • 골드바흐의 추측: 2보다 큰 짝수는 두 소수의 합으로 나타낼 수 있다.

짝수 N을 두 소수의 합으로 나타내는 표현을 골드바흐 파티션이라고 한다. 짝수 N이 주어졌을 때, 골드바흐 파티션의 개수를 구해보자. 두 소수의 순서만 다른 것은 같은 파티션이다.

입력

첫째 줄에 테스트 케이스의 개수 T (1 ≤ T ≤ 100)가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 정수 N은 짝수이고, 2 < N ≤ 1,000,000을 만족한다.

출력

각각의 테스트 케이스마다 골드바흐 파티션의 수를 출력한다.

예제 입력 1

5
6
8
10
12
100

예제 출력 1

1
1
2
1
6

더보기

Solution

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

int main(void)
{
	int T;
	bool sieve[1000001]={false, };

	for(int i=3;i<1000001;i+=2)
		sieve[i]=true;
	for(int i=3;i<1000001;i+=2)
		if(sieve[i])
			for(int j=2*i;j<1000001;j+=i)
				sieve[j]=false;

	scanf("%d", &T);

	for(int t=0;t<T;t++)
	{
		int N, count=0;

		scanf("%d", &N);

		for(int i=3;i*2<=N;i+=2)
			count+=sieve[i]&&sieve[N-i];

		printf("%d\n", N==4?1:count);
	}

	return 0;
}
728x90

문제

"럭키스톤"은 카드를 통해 대결하는 게임이다. 창식이는 럭키스톤을 자주 한다.

이 게임의 카드에는 공격력과 생명력이 표시되어있다. 왼쪽에는 공격력이, 오른쪽에는 생명력이 숫자로 적혀있다.

서로 꺼낸 카드를 비교하여 남길 카드를 결정하는 데, 카드의 비교는 다음과 같이 이루어진다.

  • 비교하는 카드의 공격력만큼 동시에 서로 상대 카드의 생명력을 깎는다. 줄어든 생명력은 다시 회복되지 않는다.
  • 생명력이 0 이하인 경우에는 카드는 죽은 상태로 전환된다.
  • 카드가 두 장 모두 남아있다면 비교를 계속한다.

요즘 따라 게임이 안 풀리는 창식이는 대전 전에 가능한 수를 미리 계산하여 최대한 이득을 챙기고 싶어 한다.

카드 2개의 공격력과 생명력이 주어지면 어떤 플레이어의 카드가 남아있을지 출력하는 프로그램을 작성해주자.

입력

첫째 줄에 플레이어 A가 꺼낸 카드의 공격력과 생명력이 주어진다.

둘째 줄에 플레이어 B가 꺼낸 카드의 공격력과 생명력이 주어진다.

카드의 공격력과 생명력은 100,000 이하의 자연수이다.

출력

플레이어 A의 카드가 남아있다면 "PLAYER A"를, 플레이어 B의 카드가 남아있다면 "PLAYER B"를 출력한다.

모두 죽은 상태라면 "DRAW"를 따옴표 없이 출력한다.

예제 입력 1

4 12
5 5

예제 출력 1

PLAYER A

더보기

Solution

#include<stdio.h>

int main(void)
{
	int info[2][2], endure[2];

	for(int i=0;i<2;i++)
		for(int j=0;j<2;j++)
			scanf("%d", &info[i][j]);

	for(int i=0;i<2;i++)
	{
		endure[i]=info[i][1]/info[(i+1)%2][0];
		endure[i]-=info[i][1]%info[(i+1)%2][0]==0;
	}

	if(endure[0]!=endure[1])
		printf("PLAYER %c\n", endure[0]>endure[1]?'A':'B');
	else
		printf("DRAW\n");
	return 0;
}
728x90

문제

다음은 한결이가 거울과 한 얘기중 일부이다.

  • 한결 : 난 아무리 생각해도 기억력이 좋은 것 같아!
  • 거울 : 양심없니?
  • 한결 : 이걸 못 믿니? 너무 어이없네 ㅋㅋ
  • 거울 : ㅋ ㅋ ㅋ ㅋ ㅋ ㅋ ㅋ ㅋ ㅋ ㅋ ㅋ
  • 한결 : 하.. 이걸 못 믿네; 내 머릿속에 지금 모든 소수가 차례대로 들어가 있거든? 니가 원하는 번째의 소수를 대답해줄게
  • 거울 : 그럼 k번째 소수가 뭔데??
  • 한결 : k번째 소수는....

솔직히 한결이는 기억력이 쓰레기다. 그래서 소수를 외우고 있지 못하다. 하지만 이렇게 허세를 부리고 나니 거울한테 참교육을 시전해주고 싶었다. 한결이를 도와 k번째 소수를 알려주자.

소수의 정의는 다음과 같다.

2 이상의 자연수 N이 1과 N을 제외하고 어떤 자연수로도 나누어 떨어지지 않을 때 소수라고 한다.

입력

자연수 K가 주어진다.(1 ≤ K ≤ 500,000)

출력

K번째 소수를 출력하자.

서브태스크 1 (5점)

  • K ≤ 5000

서브태스크 2 (20점)

  • K ≤ 40000

서브태스크 3 (75점)

문제에서 주어진 제약 조건 외 조건 없음

예제 입력 1

1

예제 출력 1

2

예제 입력 2

3

예제 출력 2

5

채점 및 기타 정보

  • 예제는 채점하지 않는다.

더보기

Solution

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

int main(void)
{
	int K, count=1, number;
	bool sieve[7368788]={false, };

	for(int i=3;i<7368788;i+=2)
		sieve[i]=true;
	for(int i=3;i<7368788;i+=2)
		if(sieve[i])
			for(int j=2*i;j<7368788;j+=i)
				sieve[j]=false;

	scanf("%d", &K);

	if(K==1)
		printf("2\n");
	else
	{
		for(number=3;count<K;number+=2)
			count+=sieve[number];
		printf("%d\n", number-2);
	}
	return 0;
}
728x90

+ Recent posts