코딩일지(2024-01-01)
이제 2024년이다!
올해는 무조건 실적을 많이 낼 것이다. 올해만을 준비했다는 마음가짐으로 한해를 가치있게 살고 싶다
[백준]1330번 두 수 비교하기
위 문제의 정답은 어렵지 않다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void) {
long long a, b;
scanf("%lld %lld", &a, &b);
if (-10000 < a && a < 10000)
{
if (-10000 < b && b < 10000)
{
if (a < b)
{
printf("<");
}
else if (a > b)
{
printf(">");
}
else
{
printf("==");
}
}
}
return 0;
}
내가 궁극적으로 해보고자 하는 것은 코드를 분산시켜서 짜보려고 한다. 헤더파일로 분리시키는 작업을 해보자.
1)함수화시키기
일단 캡슐화를 시켜서 묶어주는 방식을 취한다. 그래야지 이 꾸러미?를 헤더파일로 이식시키기가 용이하다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void compare(int a, int b);
int main(void) {
long long a, b;
scanf("%lld %lld", &a, &b);
compare(a, b);
return 0;
}
void compare(int a, int b)
{
if (-10000 < a && a < 10000)
{
if (-10000 < b && b < 10000)
{
if (a < b)
{
printf("<");
}
else if (a > b)
{
printf(">");
}
else
{
printf("==");
}
}
}
}
2)헤더파일로 코드 분산하기
일단 compare.h라는 헤더파일을 만들고 틀을 잡아준다.
//compare.h
#ifdef COMPARE_H
#define COMPARE_H
#endif // COMPARE_H
#ifdef COMPARE_H
: 만약 COMPARE_H가 정의되어 있지 않으면#define COMPARE_H
: HEADER_H 매크로를 정의한다#endif
: COMPARE_H 매크로 정의의 끝
이 자체는 하나의 템플릿이다. 따라서 템플릿 안에 템플릿을 중복해서 넣는 것도 가능하다.예를 들어,
//compare.h
#ifndef COMPARE_H
#define COMPARE_H
#define ENDING "프로그램을 종료합니다." //문자열형 상수 정의
#endif // COMPARE_H
이떄 위와 같이 #ifndef [헤더 구분자]
의 형태로 정의를 하는데 [헤더 구분자]
명명규칙은 아래와 같다.
1.헤더파일명에서 소문자를 대문자로 바꾼다.(compare → COMPARE)
2.마침표”.”를 언더바”_“로 바꾼다.
3.확장자 또한 소문자를 대문자로 바꾼다.(h → H)
4.파일 이름 앞뒤에 언더바”__“를 붙인다.(선택)
그 다음 함수의 선언부를 넣어준다.
// compare.h
#ifndef COMPARE_H
#define COMPARE_H
#define ENDING "프로그램을 종료합니다." // 문자열형 상수 정의
void foo(int a, int b);
#endif // COMPARE_H
그리고 이름은 같고, 구현부가 들어가 있는 소스파일을 개별적으로 구현해준다.
// compare.c
#include "compare.h"
#include <stdio.h>
void foo(int a, int b)
{
if (-10000 < a && a < 10000)
{
if (-10000 < b && b < 10000)
{
if (a < b)
{
printf("<");
}
else if (a > b)
{
printf(">");
}
else
{
printf("==");
}
}
}
printf("%s\n", ENDING);
}
위와 같이 만들어주었으면 이제 이를 main.c파일에 들여와야 한다.
그러기 위해서 compare.h
와compare.c
파일을 모두 들여올 필요는 없고 헤더파일만 include
해주면 알아서 compare.c
파일도 돌아가게 된다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "./compare.h"
int main(void) {
long long a, b;
scanf("%lld %lld", &a, &b);
foo(a, b);
return 0;
}
구성은 다음과 같다.
[html]다음에 블로그 하나 더 만들 일 있으면 이렇게 해보는 것도 좋겠다.
danggai라는 분의 깃허브 블로그이다.(링크)
[백준]25254번 오븐시계
위 문제는 60분을 넘어가냐 안넘어가냐, 24시를 넘어가냐 안넘아가냐로 단순하게 접근해서 풀수도 있고, 아니면 한번 더 꼬아서 생각해서 결국 나머지 연상자를 써주는 방식이 있을수 있다. 전자의 방식은 if문을 써야 하는 귀차니즘을 가져오지만, 나머지 연산자를 서주면 중괄호 그딴거 필요없이 계산연산만 해주면 된다. (분기처러 안해줘도 된다)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void) {
long long a,b,c;
scanf("%lld %lld", &a, &b);
scanf("%lld", &c);
if (0 <= a && a <= 23)
{
if (0 <= b && b <= 59)
{
// start
b = b + c;a = a + (b / 60);
printf("%lld %lld\n", a%=24, b%60);
//end
}
}
return 0;
}
printf("%lld %lld\n", a%=24, b%60);
여기서 %=24를 해준 이유는 만약 타이머를 많이 돌려서 24시간을 넘어가서 24시 13분이 떴다고 하자. 이때 문제에서는 24시를 0으로 대체하라고 출력예시부분에 나와있기 때문에 이를 참고했다.
[백준]2480번 주사위 세개
코드>
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int max(int a, int b, int c)
{
int max;
if (a > b)
{
if (a > c)
{
max = a;
}
else
{
max = c;
}
}
else
{
if (b > c)
{
max = b;
}
else
{
max = c;
}
}
return max;
}
int main(void) {
long long a,b,c;
scanf("%lld %lld %lld", &a, &b, &c);
if (0 <= a && a <= 6)
{
if (0 <= b && b <= 6)
{
if (0 <= b && b <= 6)
{
// start
if (a == b && b == c)
{
printf("%lld", 10000 + a * 1000);
}
else if (a == b || b == c )
{
printf("%lld", 1000 + b * 100);
}
else if (a == c)
{
printf("%lld", 1000 + a * 100);
}
else
{
printf("%lld", max(a,b,c)*100);
}
//end
}
}
}
return 0;
}
[백준]8393번 합
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void) {
long long n, sum=0;
scanf("%lld", &n);
for (int i = 1; i <= n; i++)
{
sum += i;
}
printf("%lld\n", sum);
return 0;
}
[백준]25304번 영수증
아래 같이 코드를 짰고, 돌아가는 것을 확인했다.
하지만 결과는 틀렸다고 나온다,
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void) {
int result=0,sum=0,n=0;
scanf("%d", &result);
scanf("%d", &n);
int items[100] = { 0, };
int cnt[100] = {0,};
for (int i = 0; i < n; i++)
{
scanf("%d %d", &items[i], &cnt[i]);
}
for (int i = 0; i <= n; i++)
{
sum += items[i] * cnt[i];
}
(sum == result) ? printf("Yes") : printf("No");
return 0;
간과한게 있기는 하겠지만 몰라서 구글링해봤다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void) {
int x, t, a, b;
scanf("%d", &x);
scanf("%d", &t);
for (int i = 0; i< t; i++)
{
scanf("%d %d", &a, &b);
x -= a * b;
}
(x == 0) ? printf("Yes") : printf("No");
return 0;
}
내 코드랑 동작은 같고 굳이 다른 부분을 지적하자면, 이 구글링해서 나온 코드는 메모리를 많이 잡아먹지 않는다. 내 코드는 int items[100] = { 0, };
와 int cnt[100] = {0,};
로 인해 메모리를 많이 잡아먹는 이슈가 있긴 하다.
하지만 그래도 왜 틀렸는지 모르겠다.
모범답안은 변수를 돌려쓰고 해당 값을 일일이 저장하지 않는다, 솔직히 차감을 해서 한번 쓰고 버리는 방식을 취한건 잘한 것 같다. 나도 메모리를 효율적으로 쓰는 알고리즘을 짜려고 노력해야 겠다.(값을 한사이클에서만 쓰고 버린다면 굳이 저장할 필요가 없다는 것을 기억하자!)
[백준]25314번 코딩은 체육과목입니다
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void) {
int n;
scanf("%d", &n);
if(n % 4==0)
{
for (int i = 0; i < (n / 4); i++)
{
printf("long ");
}
printf("int");
}
else
{
for (int i = 0; i < (n / 4)+1; i++)
{
printf("long ");
}
printf("int");
}
return 0;
}
코드리뷰를 하자면 4의 배수냐 아니냐에 따라 long을 하나 더 넣냐 넣지 않냐를 구분했다.
근데 지금 생각해보니, 그 구분은 연산을 조금더 하다가 나중에 작업해줘도 되지 않을까 하는 생각이 들었다.
무슨 말이냐면,
위 아이디어를 실제로 구현해보았다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void) {
int n;
scanf("%d", &n);
int omega;
(n % 4 == 0) ? omega = n / 4 : (omega = (n / 4) + 1);
for (int i = 0; i < omega; i++)
{
printf("long ");
}
printf("int");
return 0;
}
댓글남기기