본문 바로가기
Language/C++

[C++_백준] 2914, 1550, 2845

by 전전긍긍 2022. 2. 2.

2914. 저작권

 

문제

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

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

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

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

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

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

 

입력

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

 

출력

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

 

소스코드
#include <iostream>
using namespace std;

int main() {
	int album, mean;
	cin >> album >> mean;

	int melody = (album * mean) - album + 1;
	cout << melody << "\n";

	return 0;
}

💡이 문제의 핵심은 "평균값은 항상 올림을 해서 정수로 만들어야 한다" 이다. C++에서 올림된 몫을 구하는 방법을 알면 쉽게 풀 수 있다.

unsigned int x, y, q;

q = (x + y - 1) / y;
q = 1 + ((x - 1) / y); // if x != 0

+) "적어도"에 포인트를 잡아도 풀 수 있다. 평균값(23.23)으로 계산하였을 때 가능한 멜로디의 수는 875~912이다. 

멜로디의 개수 = 곡의 개수 * 평균값

874 = 38 * 23

912 = 38 * 24

 

평균값의 범위는 23 < mean ≤ 24 이므로 멜로디의 수의 범위는 875~912이다. "적어도"이므로 멜로디의 개수는 적어도 875가 되는 것이다. 문제에서 곡의 개수는 38, 평균값은 24로 입력 된다면, 수식은 다음과 같이 된다.

 

[참고 자료]

https://stackoverflow.com/questions/2745074/fast-ceiling-of-an-integer-division-in-c-c

 

Fast ceiling of an integer division in C / C++

Given integer values x and y, C and C++ both return as the quotient q = x/y the floor of the floating point equivalent. I'm interested in a method of returning the ceiling instead. For example, c...

stackoverflow.com


1550. 16진수

 

문제

16진수 수를 입력받아서 10진수로 출력하는 프로그램을 작성하시오.

 

입력

첫째 줄에 16진수 수가 주어진다. 이 수의 최대 길이는 6글자이다. 16진수 수는 0~9와 A~F로 이루어져 있고, A~F는 10~15를 뜻한다. 또, 이 수는 음이 아닌 정수이다.

 

출력

첫째 줄에 입력으로 주어진 16진수 수를 10진수로 변환해 출력한다.

 

소스코드
#include <iostream>
using namespace std;

int main() {
	int x;
	cin >> hex >> x;

	cout << dec << x;

	return 0;
}

💡문자함수를 사용해서 풀어보았는데 틀려서 인터넷을 찾아보았다. 생각보다 더 쉬운 방법이 있었다. 

문자함수와 아스키 코드 사용해서 푸는 것보다 더 간결하고 효율적이어서 배울 점이 많은 문제였다.

 

  • 2진법 bin(ary notation)
  • 8진법 oct(al system)
  • 10진법 dec(imal system)
  • 16진법 hex(ademical natation)

 

16진수로 x를 입력받고

cin >> hex >> x;

10진수로 x를 출력한다.

cout << dec << x;

 

[참고자료]

https://blog.naver.com/misook0721/222633607106

 

[백준 알고리즘 | 1550 - 16진수 ] 진법

//백준 알고리즘 1550 16진수 코딩 독학 D+88 https://www.acmicpc.net/problem/1550 진법을 변환하는 문...

blog.naver.com


2845. 파티가 끝나고 난 뒤

 

문제

파티가 끝나고 나면, 사람들은 누가 파티에 왔는지와 얼마나 많은 사람들이 왔는지를 궁금해한다. 보통 파티는 매우 크게 열리기 때문에, 정확하게 몇 명이 참가했는지 알 수가 없다.

지난주 토요일에 상근이는 자신의 3학년 진학을 기념하면서 매우 성대한 파티를 열었다. 그리고, 상근이는 1m2당 몇 명의 사람이 있었는지 알고있다.

상근이의 파티는 정말 엄청난 규모였기 때문에, 대부분의 신문에도 기사가 실렸다. 상근이는 서로 다른 5개의 신문을 보면서 그 기사에 적혀져있는 참가자의 수를 적었다.

상근이는 자신이 알고있는 참가자의 수가 정확하다고 생각한다. 각 신문 기사에 실려있는 참가자의 수가 몇 명 만큼 잘못되어있는지 구하는 프로그램을 작성하시오.

 

입력
 

첫째 줄에 1m2당 사람의 수 L (1 ≤ L ≤ 10)과 파티가 열렸던 곳의 넓이 P (1 ≤ P ≤ 1000)가 주어진다.

둘째 줄에는 각 기사에 실려있는 참가자의 수가 주어진다. 106보다 작은 양의 정수 5개가 주어진다.

 

출력
 

출력은 첫째 줄에 다섯 개의 숫자를 출력해야 한다. 이 숫자는 상근이가 계산한 참가자의 수와  각 기사에 적혀있는 참가자의 수의 차이이다.

 

소스코드
#include <iostream>
using namespace std;

int main() {
	int l, p;
	cin >> l >> p;

	int x = l * p;

	int y;
	for (int i = 0; i < 5; i++)
	{
		cin >> y;
		cout << y - x << " ";
	}
	return 0;
}