728x90
 

1712번: 손익분기점

월드전자는 노트북을 제조하고 판매하는 회사이다. 노트북 판매 대수에 상관없이 매년 임대료, 재산세, 보험료, 급여 등 A만원의 고정 비용이 들며, 한 대의 노트북을 생산하는 데에는 재료비와 인건비 등 총 B만원의 가변 비용이 든다고 한다. 예를 들어 A=1,000, B=70이라고 하자. 이 경우 노트북을 한 대 생산하는 데는 총 1,070만원이 들며, 열 대 생산하는 데는 총 1,700만원이 든다. 노트북 가격이 C만원으로 책정되었다고 한다. 일반적으로

www.acmicpc.net

#include <iostream>
using namespace std;

int main() {
	long a, b, c;
	cin >> a >> b >> c;
	int n = 0;
	if (b >= c) {
		cout << -1;
		return 0;
	}
	cout << a / (c - b) + 1;
	return 0;
}
728x90
728x90
 

1085번: 직사각형에서 탈출

첫째 줄에 x y w h가 주어진다. w와 h는 1,000보다 작거나 같은 자연수이고, x는 1보다 크거나 같고, w-1보다 작거나 같은 자연수이고, y는 1보다 크거나 같고, h-1보다 작거나 같은 자연수이다.

www.acmicpc.net

#include <iostream>
using namespace std;

int main() {
	int x, y, w, h;
	cin >> x >> y >> w >> h;
	int minWidth = (w - x > x) ? x : w - x;
	int minHeight = (h - y > y) ? y : h - y;
	cout << ((minWidth > minHeight) ? minHeight : minWidth);
	return 0;
}
728x90
728x90

단계별로 풀어보기 수학1의 6단계 문제

 

10250번: ACM 호텔

문제 ACM 호텔 매니저 지우는 손님이 도착하는 대로 빈 방을 배정하고 있다. 고객 설문조사에 따르면 손님들은 호텔 정문으로부터 걸어서 가장 짧은 거리에 있는 방을 선호한다고 한다. 여러분은 지우를 도와 줄 프로그램을 작성하고자 한다. 즉 설문조사 결과 대로 호텔 정문으로부터 걷는 거리가 가장 짧도록 방을 배정하는 프로그램을 작성하고자 한다. 문제를 단순화하기 위해서 호텔은 직사각형 모양이라고 가정하자. 각 층에 W 개의 방이 있는 H 층 건물이라고 가정

www.acmicpc.net

#include <iostream>
using namespace std;

int main() {
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);
	int t;
	cin >> t;
	for (int i = 0; i < t; i++) {
		int height, width, customerNumber;
		cin >> height >> width >> customerNumber;
		int n = 1;
		int floor = 1;
		int room = 1;
		if (customerNumber % height == 0) room = customerNumber / height;
		else room = customerNumber / height + 1;
		if(customerNumber % height == 0) floor = customerNumber % height + height;
		else floor = customerNumber % height;
		cout << floor * 100 + room << '\n';
	}
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 1712 손익분기점  (0) 2020.02.02
[백준] 1085번 직사각형에서 탈출  (0) 2020.02.02
[백준] 11726번 2×n 타일링  (0) 2020.02.01
[백준] 10844번 쉬운 계단 수  (0) 2020.01.31
[백준] 2292번 벌집  (0) 2020.01.31
728x90

입력을 받을 때에는

n = int(input())

보다는

from sys import stdin
n = int(stdin.readline())

이 코드가 더 빠르다. 한 줄에 입력 개수가 한 개일지라도 input()보다는 sys.stdin.readline()이 더 빠르다.

 

입력받아야 할 것이 한 줄에 여러 개라면 input()보다 readline() 함수를 이용하는 것이 훨씬 더 빠르다.

li = list(map(int, stdin.readline().split()))

readline() 함수 뒤에 split() 함수를 연이어서 호출하면 아예 이렇게 list로 받는 것이 가능하다.

게다가 문자열이 아니라 아예 int로 바꿔서까지 저장할 수 있으니 정말 편리하다.

 

입력이 만약에 이렇게 들어온다면?

3 3
1 1 0
1 1 1
1 0 1
1 1 1

이 코드로 입력받을 수 있다.

n, m = list(map(int, stdin.readline().split()))
li = []
for i in range(n):
    li.append(list(map(int, stdin.readline().split())))

대입 연산자의 우측에 list가 있고 대입연산자의 좌측에 list의 크기 만큼 개수의 변수가 있으면 변수 각각에 list의 원소가 저장된다. n, m 이렇게 두 개를 받을 때에도 readline().split()을 쓰면 유용하다.

사실 이 정도 두 개 변수 받을 때 input() 대신 readline()을 쓴다고 시간초과 문제가 해결되는 것은 아니고

속도 향상의 핵심은 저 for문이다.

저 for문을 수행하고 나면 이차원 list(이차원 배열)가 만들어진다.

 

만약에 저 for문을

for i in range(n):
	for j in range(m):
    		li.append(int(input()))

이렇게 이중 for문을 사용해서 input() 함수를 통해 입력받는다면 속도는 훨씬 느려진다. for문 자체도 이중이기 때문에 겉보기로만 대충 구한 시간복잡도이지만 시간복잡도가 O(n)에서 O(n^2)로 훨씬 커졌고 함수 자체도 readline() 함수보다 input() 함수가 더 느리다. 따라서 이 코드는 위의 코드보다 훨씬 느리다.

 

만약 위와 같이 한 줄에 여러 데이터를 공백을 구분하는게 아니라

5
5
4
3
2
1

이렇게 한 줄에 한 개의 데이터만 주어진다면?

 

앞의 코드에서는 append() 함수를 이용해서 빈 리스트에 입력받은 값을 저장해줬다.

하지만 이 경우 리스트를 먼저 초기화해주고 인덱스를 이용해서 접근해서 값을 저장하면 속도가 조금 더 개선된다.

li = [0] * n
for i in range(n):
	li[i] = int(sys.stdin.readline())

이렇게 li[i]로 접근해서 값을 저장한다면

 

li = []
for i in range(n):
	li.append(int(sys.stdin.readline()))

이렇게 빈 리스트에 append() 함수를 이용해 값을 저장하는 것보다 조금 더 빨라진다.

 

 

백준 온라인 저지 사이트에

리스트를 초기화해놓고 인덱스로 접근하는 이 코드로 제출하면

n = int(input())
li = [0] * n
from sys import stdin
for i in range(n):
    li[i] = int(stdin.readline())

s = ""
li.sort()
for i in li:
    s += (str(i) + '\n')
print(s)

1468ms가 걸리지만

append() 함수로 데이터를 덧붙이는 식으로 하면

n = int(input())
li = []
from sys import stdin
for i in range(n):
    li.append(int(stdin.readline()))

s = ""
li.sort()
for i in li:
    s += (str(i) + '\n')
print(s)

1592ms가 걸리는 것을 볼 수 있다.

 

그리고 출력할 때에 줄바꿈을 해야 한다면

for i in li:
	print(i)

이렇게 하는 것은 매우 비효율적이고

 

s = ""
for i in li:
    s += (str(i) + '\n')
print(s)

이렇게 s라는 string 변수에 줄바꿈 문자까지 합친 문자열을 계속 계속 덧붙여서 저장하고 나중에 한번에 s를 출력하는 것이 더 빠르다.

 

실제로 백준 온라인 저지 사이트에서 돌려보았다.

n = int(input())
li = [0] * n
from sys import stdin
for i in range(n):
    li[i] = int(stdin.readline())

li.sort()
for i in li:
    print(i)

이 코드를 제출하면

1708ms가 걸리지만

출력 부분만 바꿔서

n = int(input())
li = [0] * n
from sys import stdin
for i in range(n):
    li[i] = int(stdin.readline())

s = ""
li.sort()
for i in li:
    s += (str(i) + '\n')
print(s)

이렇게 돌리면

1468ms가 걸리는 것을 볼 수 있다.

 

그리고 여기에서 또 한 번 느끼는 것은 메모리 양과 수행시간은 반비례 한다는 것이다.

역시 하나를 얻으려면 하나를 포기해야 한다는 것은 세상 만물의 진리인 것 같다.

메모리 사용량을 줄이려고 s라는 변수를 안 쓰고 print 하면 메모리는 덜 쓸 수 있지만 시간이 오래 걸리고

시간을 줄이려고 s라는 문자열 변수를 만들어서 출력하면 메모리는 조금 더 쓰지만 시간을 줄일 수 있다.

 

정리하자면

1. input()보다는 sys.readline()을 쓰자.

2. 빈 리스트에 append()로 추가하는 것보단 입력 받을 개수 만큼 초기화된 리스트에 인덱스를 이용해서 접근해서 그 위치에 직접 입력받자.

3. 줄바꿈 할때엔 print()가 아니라 '\n', for문 마다 출력하지 말고 문자열 변수에 저장해놓고 한 번에 출력하자.

728x90
728x90

깃허브 명령어 git add를 이용하여 추가하려고 하면 이런 에러가 자주 발생한다.

warning: LF will be replaced by CRLF in gradlew.

The file will have its original line endings in your working directory.

 

그래서 검색해봤더니 이렇게 하면 된다고 한다.

https://blog.naver.com/lovelylucia/221743687212

git config --global core.autocrlf true

이 한 줄을 입력해주면 해결된다.

이제 아까 안 됐던 add가 멀쩡히 잘 되는 것을 볼 수 있다.

728x90

'GitHub' 카테고리의 다른 글

[GitHub] 깃허브 fatal: unable to access, push 안 됨  (3) 2020.01.21
728x90
 

11726번: 2×n 타일링

2×n 크기의 직사각형을 1×2, 2×1 타일로 채우는 방법의 수를 구하는 프로그램을 작성하시오. 아래 그림은 2×5 크기의 직사각형을 채운 한 가지 방법의 예이다.

www.acmicpc.net

동적 계획법으로 풀었다.

규칙이 있다.

2 x n을 채우는 방법의 수 = 2 x (n - 1)을 채우는 방법의 수 + 2 x (n - 2)를 채우는 방법의 수이다.

int의 범위를 벗어날 수 있으니 애초에 저장할 때 10007로 나눈 나머지를 저장해주었다.

#include <iostream>
using namespace std;

int main() {
	int n;
	cin >> n;
	int* arr = new int[n];
	arr[0] = 1;
	arr[1] = 2;
	for (int i = 2; i < n; i++) {
		arr[i] = (arr[i - 1] + arr[i - 2]) % 10007;
	}
	cout << arr[n - 1];
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 1085번 직사각형에서 탈출  (0) 2020.02.02
[백준] 10250번 ACM 호텔  (0) 2020.02.01
[백준] 10844번 쉬운 계단 수  (0) 2020.01.31
[백준] 2292번 벌집  (0) 2020.01.31
[백준] 2193번 이친수  (0) 2020.01.31
728x90
 

10844번: 쉬운 계단 수

첫째 줄에 정답을 1,000,000,000으로 나눈 나머지를 출력한다.

www.acmicpc.net

#include <iostream>
using namespace std;

int main() {
	int n;
	cin >> n;
	int* zero = new int[n];
	int* one = new int[n];
	int* two = new int[n];
	int*  three= new int[n];
	int* four = new int[n];
	int* five = new int[n];
	int* six = new int[n];
	int* seven = new int[n];
	int* eight = new int[n];
	int* nine = new int[n];
	zero[0] = 0;
	one[0] = 1;
	two[0] = 1;
	three[0] = 1;
	four[0] = 1;
	five[0] = 1;
	six[0] = 1;
	seven[0] = 1;
	eight[0] = 1;
	nine[0] = 1;
	for (int i = 1; i < n; i++) {
		zero[i] = one[i - 1];
		one[i] = (zero[i - 1] + two[i - 1]) % 1000000000;
		two[i] = (one[i - 1] + three[i - 1]) % 1000000000;
		three[i] = (two[i - 1] + four[i - 1]) % 1000000000;
		four[i] = (three[i - 1] + five[i - 1]) % 1000000000;
		five[i] = (four[i - 1] + six[i - 1]) % 1000000000;
		six[i] = (five[i - 1] + seven[i - 1]) % 1000000000;
		seven[i] = (six[i - 1] + eight[i - 1]) % 1000000000;
		eight[i] = (seven[i - 1] + nine[i - 1]) % 1000000000;
		nine[i] = eight[i - 1];
	}
	int sum = 0;
	sum = zero[n - 1];
	sum = (sum + one[n - 1]) % 1000000000;
	sum = (sum + two[n - 1]) % 1000000000;
	sum = (sum + three[n - 1]) % 1000000000;
	sum = (sum + four[n - 1]) % 1000000000;
	sum = (sum + five[n - 1]) % 1000000000;
	sum = (sum + six[n - 1]) % 1000000000;
	sum = (sum + seven[n - 1]) % 1000000000;
	sum = (sum + eight[n - 1]) % 1000000000;
	sum = (sum + nine[n - 1]) % 1000000000;
	cout << sum;
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 10250번 ACM 호텔  (0) 2020.02.01
[백준] 11726번 2×n 타일링  (0) 2020.02.01
[백준] 2292번 벌집  (0) 2020.01.31
[백준] 2193번 이친수  (0) 2020.01.31
[백준] 1193번 분수찾기  (0) 2020.01.31
728x90
 

2292번: 벌집

위의 그림과 같이 육각형으로 이루어진 벌집이 있다. 그림에서 보는 바와 같이 중앙의 방 1부터 시작해서 이웃하는 방에 돌아가면서 1씩 증가하는 번호를 주소로 매길 수 있다. 숫자 N이 주어졌을 때, 벌집의 중앙 1에서 N번 방까지 최소 개수의 방을 지나서 갈 때 몇 개의 방을 지나가는지(시작과 끝을 포함하여)를 계산하는 프로그램을 작성하시오. 예를 들면, 13까지는 3개, 58까지는 5개를 지난다.

www.acmicpc.net

동적계획법으로 풀었다.

2-tuple인 pair를 만들어서 첫 번째 원소에는 1로부터 i만큼 떨어져있는 벌집들 중 가장 작은 번호를 가진 벌집의 번호를, 두 번째 원소에는 1로부터 i만큼 떨어져 있는 벌집들 중 가장 큰 번호를 가진 벌집의 번호를 저장해서 벡터에 저장했다.

#include <iostream>
#include <tuple>
#include <vector>
using namespace std;

int main() {
	int n;
	cin >> n;
	vector<pair<int, int>> room;
	room.push_back(make_pair(1, 1));
	room.push_back(make_pair(2, 7));
	int i = 2;
	while (room[i - 1].second < n) {
		room.push_back(make_pair(room[i - 1].second + 1, room[i - 1].second + 6 * i));
		i++;
	}
	if (n == 1) cout << 1;
	else cout << i;
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 11726번 2×n 타일링  (0) 2020.02.01
[백준] 10844번 쉬운 계단 수  (0) 2020.01.31
[백준] 2193번 이친수  (0) 2020.01.31
[백준] 1193번 분수찾기  (0) 2020.01.31
[백준] 2751번 수 정렬하기 2  (0) 2020.01.31
728x90
 

2193번: 이친수

0과 1로만 이루어진 수를 이진수라 한다. 이러한 이진수 중 특별한 성질을 갖는 것들이 있는데, 이들을 이친수(pinary number)라 한다. 이친수는 다음의 성질을 만족한다. 이친수는 0으로 시작하지 않는다. 이친수에서는 1이 두 번 연속으로 나타나지 않는다. 즉, 11을 부분 문자열로 갖지 않는다. 예를 들면 1, 10, 100, 101, 1000, 1001 등이 이친수가 된다. 하지만 0010101이나 101101은 각각 1, 2번 규칙에 위배되

www.acmicpc.net

동적계획법으로 풀었다.

i번째 0의 개수 = i - 1번째 0의 개수 + i - 1번째 1의 개수

i번째 1의 개수 = i - 1번째 0의 개수

 

i번째에 1이 나오려면 i-1번째에 0일 수밖에 없다. i-1번째가 1이면 i번째가 1이면 안되니까. (연속으로 1이 나오면 안 되니까)

i번째에 0이 나오려면 i-1번째가 0이든 1이든 상관없다. 0이 연속으로 나오는 것은 상관 없으니까.

#include <iostream>
using namespace std;

int main() {
	int n;
	cin >> n;
	long* zero = new long[n];
	long* one = new long[n];
	zero[0] = 0;
	one[0] = 1;
	for (int i = 1; i < n; i++) {
		zero[i] = zero[i - 1] + one[i - 1];
		one[i] = zero[i - 1];
	}
	cout << zero[n - 1] + one[n - 1];
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 10844번 쉬운 계단 수  (0) 2020.01.31
[백준] 2292번 벌집  (0) 2020.01.31
[백준] 1193번 분수찾기  (0) 2020.01.31
[백준] 2751번 수 정렬하기 2  (0) 2020.01.31
[백준] 10828번 스택  (0) 2020.01.31
728x90
 

1193번: 분수찾기

첫째 줄에 X(1 ≤ X ≤ 10,000,000)가 주어진다.

www.acmicpc.net

#include <iostream>
using namespace std;

int main() {
	int n;
	cin >> n;
	if (n == 1) {
		cout << "1/1";
		return 0;
	}
	int index = 2;
	int sum = 1;
	while (true) {
		if (sum > n) {
			sum -= (index - 2);
			int numerator;
			int denominator;
			if (index % 2 == 1) {
				numerator = 1;
				denominator = index - 1;
				while (sum != n) {
					numerator++;
					denominator--;
					sum++;
				}
			}
			else {
				numerator = index - 1;
				denominator = 1;
				while (sum != n) {
					numerator--;
					denominator++;
					sum++;
				}
			}
			cout << numerator << "/" << denominator;
			break;
		}
		else if (sum == n) {
			if (index % 2 == 0) {
				cout << 1 << "/" <<index - 1;
			}
			else {
				cout << index - 1 << "/" << 1;
			}
			break;
		}
		else {
			sum += index;
			index++;
		}
	}
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 2292번 벌집  (0) 2020.01.31
[백준] 2193번 이친수  (0) 2020.01.31
[백준] 2751번 수 정렬하기 2  (0) 2020.01.31
[백준] 10828번 스택  (0) 2020.01.31
[백준] 10814번 나이순 정렬  (0) 2020.01.30

+ Recent posts