😈 알고리즘/💻 백준

💻 10818번 문제 : 최소, 최대 🙋

Buᐢ༝ᐢy 2022. 9. 24. 19:41
10818번: 최소, 최대
https://www.acmicpc.net/problem/10818
#include <iostream>
using namespace std;

int main()
{
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);

	int N = 0;
	int A[1000000] = {};
	int input = 0;
	int min = 0;
	int max = 0;
	
	cin >> N;

	for (int i = 0; i < N; i++)
	{
		cin >> input;
		A[i] = input;

		if (i == 0)
		{
			min = A[i];
			max = A[i];
		}

		else
		{
			if (A[i] < min)
			{
				min = A[i];
			}

			if (A[i] > max)
			{
				max = A[i];
			}
		}
	}

	cout << min << " " << max;
}
메모리 (KB)시간 (ms)코드 길이 (B)
2020108456

🙋 더 알아보기

어제 문제를 풀면서 안 좋은 습관에 대해 이야기했다. 해당 문제는 아래에 북마크를 걸어두었다.

💻 1110번 문제 : 더하기 사이클 🙋
include int main() { int input; int count= 0; int A = -1; scanf("%d", &input); while(A!=input) { if(count ==0) A = input; A=(A%10)*10+(A/10+A%10)%10; count++; } printf("%d",count); } 우선 이 문제는 처음에 잘 풀어놓고 확인한답시고 printf("%d",count);가 아닌 printf("count : %d",count); 로 적어서 틀렸다. 그 이후로 계속 이 방식이 아닌 거 같아 거의 4시간 가까이 도전했다...
https://chicken-scratch.tistory.com/60

위의 습관과 더불어 문제를 풀 때 고민이 생기기 시작했다.

🤔
어떻게 해야 효율적으로 알고리즘 문제를 풀 수 있을까?

모든 것을 고려하여 아주 잘 짠 코드를 지금 당장 짤 수는 없다. C++을 시작한지 그리 오래 되지도 않았을 뿐더러, 안 좋은 습관이 있는 것조차 바로 어제 알게 된 초보이기 때문이다. 그래서 앞으로 고려해야 될 것들이 더 늘겠지만 2022년 09월 24일 기준으로 다음 항목들을 지키면서 코드를 짤 예정이다.

메모리 및 시간

현재 백준에서 알고리즘 문제를 단계별로 풀고있다. 문제를 풀면 하단 이미지처럼 결과가 출력된다.

제출 번호아이디문제결과메모리시간언어코드 길이제출한 시간

사실 이전까지 제일 신경 썼던 항목은 코드 길이였다. 그래서 알고리즘 문제풀이 포스팅의 처음 형식도 메모리와 시간은 적지 않은, 코드 길이만 기재했었다. 당시의 생각으로는 코드가 길면 길 수록 메모리나 시간이 더 걸리지 않을까였기 때문이다.

그래서 코드 길이보다는 메모리와 시간을 더 줄일 수 있는 코드를 짜기 위해 여러 가지 시도를 할 예정이다. 시간이 오래 걸리기 때문에 해당 문제를 풀고 난 후 여유시간이 있을 때 해야겠다. 안 그래도 이번 문제 역시 어떻게 하면 메모리와 시간을 더 줄일 수 있을까? 다른 사람들의 결과는 어떨까? 라는 생각 때문에 다른 일 하다가도 신경이 쓰였다. 결국에는 다음처럼 내가 아는 선에서 메모리와 시간을 가장 많이 줄였다.

빈 칸이 있는 건 틀렸기 때문이다 😉

나중에 어려운 문제를 접하게 되면 저번에도 확인했지만 시간 제한 때문에 틀리는 경우도 있다. 위 이미지를 봐도 맨 위에 있는 제출 내용의 코드 길이가 가장 김에도 불구하고 메모리와 시간은 현저히 적다는 것을 알 수 있다. 현재 나의 수준에서는 코드 길이를 따져가면서 극한으로 줄이는 것보다 누가 봐도 이해하기 쉬운 코드를 짜는 걸 우선으로 두려고 한다.

변수의 초기화

1년 가까이 코딩을 해왔음에도 불구하고 제대로 문법 공부를 한 건 최근이다. 이전에는 내가 원하는 기능이 구현만 되면 코드가 효율적이든 아니든 그대로 사용했다. 프로젝트 규모가 다 작았기에 망정이지, 만일 현업이었다면 욕을 엄청 먹었을 것이다… 변수를 초기화 시키지 않고 그냥 사용하던 습관도 매 맞을 안 좋은 습관 중 하나일 것이라고 생각한다.

int a;
int b = 0;

초기화는 선언과 동시에 값을 넣어주는 건데, 이후에 할당하기 때문에 아무 생각 없이 쓰다가 어제 이런 습관 때문에 문제를 틀리는 것 맛 보고 나니 앞으로는 코드가 길어져도 초기화를 해야겠다는 생각이 들었다.

// ... 
		if (i == 0)
		{
			min = A[i];
			max = A[i];
		}

위 코드에서도 이 부분에 대해 실수했다.

	int min = 0;
	int max = 0;

// ... 중략

	if (i == 0)
		{
			min, max = A[i];
		}

처음에 초기화를 한 후에 밑에서 처음 인덱스 값을 min, max에 넣어줄 때 이렇게 작성했었다. 이 문제는 맞았을까?

→ 당연히 틀렸다.

minA[i]의 값이 아닌 0으로 남아있다. 그래서 오늘 또 아… 변수는 웬만하면 한 줄에서 같이 초기화하거나 값을 할당하는 건 안 좋댔는데…, 게다가 할당 조차 방법이 틀렸어…! 나는 멍청이야…! 라는 생각이 들어 이렇게까지 글을 작성하게 되었다. 😊 다르게 생각하면, 이제라도 알아서 얼마나 다행인가? 싶기도 하다.

입출력 방식은… C ? C++ ?

🤔 C++ 문제인데 C로 푸는 이유가 뭘까?
2022년 09월 18일, 백준 에서 단계별로 문제를 풀고 있는데 같은 C++로 풀었음에도 불구하고 메모리 크기가 거의 반 정도 다른 것을 확인할 수 있다. 라는 궁금증으로부터 이 글이 작성되었다. 메모리 크기가 다른 두 코드를 살펴본 결과 다음과 같았다.
https://chicken-scratch.tistory.com/35

위 글은 같은 C++로 푼 문제 제출한 사람들의 메모리가 왜 다를까?에서 궁금증이 생겨 작성한 포스팅이다. C 혹은 C++로 풀었는지에 대한 차이로 메모리가 달랐다. 현재 문제 역시 총 3가지 방법으로 풀며 비교해보았다.

#include <iostream>
using namespace std;

int main()
{
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);

	int N = 0;
	int A[1000000] = {};
	int input = 0;
	int min = 0;
	int max = 0;
	
	cin >> N;

	for (int i = 0; i < N; i++)
	{
		cin >> input;
		A[i] = input;

		if (i == 0)
		{
			min = A[i];
			max = A[i];
		}

		else
		{
			if (A[i] < min)
			{
				min = A[i];
			}

			if (A[i] > max)
			{
				max = A[i];
			}
		}
	}

	cout << min << " " << max;
}
메모리 (KB)시간 (ms)코드 길이 (B)
2020108456

C++ 입출력, 근데 C와의 비동기화를 곁들인…

#include <iostream>
using namespace std;

int main()
{
	int N = 0;
	int A[1000000] = {};
	int input = 0;
	int min = 0;
	int max = 0;
	
	cin >> N;

	for (int i = 0; i < N; i++)
	{
		cin >> input;
		A[i] = input;

		if (i == 0)
		{
			min = A[i];
			max = A[i];
		}

		else
		{
			if (A[i] < min)
			{
				min = A[i];
			}

			if (A[i] > max)
			{
				max = A[i];
			}
		}
	}

	cout << min << " " << max;
}
메모리 (KB)시간 (ms)코드 길이 (B)
2020448404

그저 동기화가 되었을 뿐인데 위에 있는 같은 C++ 입출력 코드와 4배 이상 차이가 난다.

#include <stdio.h>

int main()
{
	int N = 0;
	int M[1000000] = {};
	int min = 0;
	int max = 0;
	scanf("%d", &N);

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

		if (i == 0)
		{
			min = M[i];
			max = M[i];
		}

		else
		{
			if (max < M[i])
			{
				max = M[i];
			}

			if (min > M[i])
			{
				min = M[i];
			}
		}
	}

	printf("%d %d", min, max);
}
메모리 (KB)시간 (ms)코드 길이 (B)
4900176361

C로 풀었음에도 불구하고 메모리 크기가 4배가 넘는다… 왜지? 나중에 찾아봐야겠다.

C++을 C와 비동기시켜주는 코드 2줄

cin.tie(NULL);

ios_base::sync_with_stdio(false);

이 두 코드를 사용하게 되면 C의 입출력인 scanf, printf보다 빠르다고 한다. 다만 제약사항이 생기니 상황에 알맞게 사용하는게 제일이다.

  1. 비동기화를 하게 되면 C의 문법을 섞어 쓸 수 없다.
  1. 싱글쓰레드에서만 가능하여 현업에서는 지양한다.

아무튼, 언젠가 시간을 고려해야 하는 문제들을 위해 이런 습관들 + α 를 생각하며 알고리즘 공부를 이어나갈 생각이다. 그리고 이전까지의 안 좋은 습관들은 단순히 알고리즘 문제에만 국한되지 않고, 프로그래밍 습관이기 때문에 주의할 필요가 있다.


Uploaded by N2T