일상

프로그래밍 입문 실습시험 후기

LUNAV 2022. 12. 4. 16:40

난이도(높을수록 어려움): 5/10

=> 하라는 것만 하면 됐고, 가장 나중에 배운 포인터와 구조체를 중점으로 출제했기 때문.

다만, 프로젝트2 1번 문제를 풀지 않았거나 알고리즘에 대해 전혀 모르는 학생이라면 align_array 함수를 프로그래밍하는 쪽에서 정렬에 막혔을 가능성이 있어보였다.

또한

  1. 앨리스에서 문제 출제에 오류가 있어 5분 늦게 시작해 8시 5분까지 진행했다는 점.
    (책 내용을 벼락치기한 경우 조금씩 잊었을 수 있었던 점.)
  2. 교수님이 문제에서도 sum_point를 avg_point로 잘못 적었다는 점.

이런것들 때문에 곤란한 학생도 생각해서 산정한 점수.


문제와 입출력 예시는 다음과 같다.

구현 예시를 참고하여 다음 조건을 수행하도록 하는 프로그램을 작성하세요.
(작성한 함수들은 메인함수를 포함한 다른 함수에서 자유롭게 사용 가능)

#1. (5점) 점의 좌표(x,y)를 멤버로 가지는 POINT 구조체를 선언한다.

점의 좌표는 정수형으로 할 것
typedef 이용하여 자료형명을 POINT로 할 것
#2. (10점) x좌표가 최솟값을 가지는 (x,y)를 출력하는 min_point 함수를 작성한다.

단, x좌표값이 같은 경우 y좌표값이 최솟값을 가지는 (x,y)출력
HINT: 입력 좌표의 x,y값의 범위는 1~99이다.
이 때, 함수의 인자 및 반환값은 바꾸지 말 것
출력 형식은 printf(“최솟값 출력: “);와 print_point 함수 이용
#3. (10점) y좌표가 최댓값을 가지는 (x,y)를 출력하는 max_point 함수를 작성한다.

단, y좌표값이 같은 경우 x좌표가 최댓값을 가지는 (x,y)출력
HINT: 입력 좌표의 x,y값의 범위는 1~99이다.
이 때, 함수의 인자 및 반환값은 바꾸지 말 것
출력 형식은 printf(“최댓값 출력: “);와 print_point 함수 이용
#4. (10점) x,y좌표의 누적 좌표값 (x,y)을 출력하는 sum_point 함수를 작성한다.

이 때, 함수의 인자 및 반환값은 바꾸지 말 것
출력 형식은 printf(“누적값 출력: “);와 print_point 함수 이용
#5. (10점) 두 점의 좌표를 맞바꾸는 swap_point 함수를 작성한다.

이 때, 함수의 인자 및 반환값은 바꾸지 말 것
#6. (20점) 주어진 구조체 배열에 대하여 x좌표를 기준으로 오름차순(작은 값부터 큰 값 순서로 정렬)으로 정렬하는 align_array 함수를 작성한다.

HINT: swap_point 사용 (반드시 사용해야 하는 것은 아님)
단, x좌표 값이 같은 경우, y좌표를 기준으로 오름차순으로 정렬
이 때, 함수의 인자 및 반환값은 바꾸지 말 것
출력 형식은 printf(“정렬 후: “); 와
for (int i = 0; i < array_size; i++)
print_point(&p[i]); 이용
#7. (5점) 구조체 배열의 크기(좌표의 갯수)는 상수로 고정시키지 않고 array_size라는 전역변수로 정의하며 sizeof 함수를 이용하여 구한다. (채점 시, 좌표의 갯수 및 좌표값을 변경하여 채점할 예정)

#8. (30점) 메인함수에서 다음 입력을 받아 조건에 맞게 수행하도록 구현하세요.

입력 변수: num(정수형)
num이 1인 경우: 함수 min_point 수행
num이 2인 경우: 함수 max_point 수행
num이 3인 경우: 함수 avg_point 수행
num이 4인 경우: 함수 align_array 수행
num이 5인 경우: printf(“프로그램을 종료합니다.\n”); 출력 후 종료
입력이 1~5가 아닌 경우, printf(“다시 입력하세요.\n\n”);가 출력 되도록 한다.

 

 

내가 짰던 코드는 다음과 같다.

#include <stdio.h>

int array_size;
typedef struct POINT {
    int x;
    int y;
} POINT;

/* 출력 부분: 수정하지 마세요 */ 
void print_point(POINT *p)
{
    printf("(%d, %d) ", p->x, p->y);
}
/* ------------------------- */

void min_point(POINT *p)
{
    POINT tmp;
    for(int i = 0; i <array_size - 1; i++){
        for(int j = 0; j < array_size - i - 1; j++){
            if(p[j].x > p[j+1].x){
                tmp = p[j];
                p[j] = p[j+1];
                p[j+1] = tmp;
            }
            if(p[j].x == p[j+1].x && p[j].y > p[j+1].y){
                // POINT tmp;
                tmp = p[j];
                p[j] = p[j+1];
                p[j+1] = tmp;
            }
        }

    } 
    
    printf("최솟값 출력: "); //수정하지 마세요.
    print_point(&p[0]);
    printf("\n\n"); //수정하지 마세요.
}

void max_point(POINT *p)
{
    POINT tmp;

   for(int i = 0; i <array_size - 1; i++){
        for(int j = 0; j < array_size - i - 1; j++){
            if(p[j].y < p[j+1].y){
                tmp = p[j];
                p[j] = p[j+1];
                p[j+1] = tmp;
            }
            if(p[j].y == p[j+1].y && p[j].x < p[j+1].x){
                // POINT tmp;
                tmp = p[j];
                p[j] = p[j+1];
                p[j+1] = tmp;
            }
        }
    } 

    printf("최댓값 출력: "); //수정하지 마세요.
    print_point(&p[0]);
    printf("\n\n"); //수정하지 마세요.
}

void sum_point(POINT *p)
{
    POINT sumArr = {0, 0};
    for(int i = 0; i <array_size; i++){
        sumArr.x += p[i].x;
        sumArr.y += p[i].y;
    }

    printf("누적값 출력: "); //수정하지 마세요.
    print_point(&sumArr);
    printf("\n\n"); //수정하지 마세요.
}


void swap_point(POINT *point1, POINT *point2)
{
    POINT tmp;

    POINT *pointPtr1, *pointPtr2, *tmpPtr;
    pointPtr1 = point1;
    pointPtr2 = point2;
    tmpPtr = &tmp;

    tmpPtr = pointPtr1;
    pointPtr1 = pointPtr2;
    pointPtr2 = tmpPtr;
}

void align_array(POINT *p)
{
    POINT tmp;
    for(int i = 0; i <array_size - 1; i++){
        for(int j = 0; j <array_size - i - 1; j++){
            if(p[j].x > p[j+1].x){
                tmp = p[j];
                p[j] = p[j+1];
                p[j+1] = tmp;
            } else if(p[j].x == p[j+1].x && p[j].y > p[j+1].y){
                tmp = p[j];
                p[j] = p[j+1];
                p[j+1] = tmp;
            }
        }
    }
    /* 출력 부분: 수정하지 마세요 */
    printf("정렬 후: ");
    for (int i = 0; i < array_size; i++)
        print_point(&p[i]);
    printf("\n\n");
    /* ------------------------- */
}

int main(void)
{
    /* 입력 부분: 수정하지 마세요 */ 
    int num;
    POINT array[] = {
        {7,20}, {3,20}, {15,19}, {7,3}, {15,11}, {8,20}, {18,15}, {9,16}, {18,2}, {7,5}, {3,3}, {5,8}
    };
    /* ------------------------- */
    
    array_size = sizeof(array)/sizeof(POINT);
    POINT *arrayPtr;
    arrayPtr = array;
    
    /* 출력 부분: 수정하지 마세요 */ 
    printf("입력 좌표: ");
    for (int i = 0; i < array_size; i++)
        print_point(&array[i]);
    printf("\n\n");
    /* ------------------------- */
    
    // printf("수행하고자 하는 번호를 입력하세요: (1:최솟값 출력, 2:최댓값 출력, 3:누적값 출력: 4:배열 정렬, 5: 종료)\n"); //자유롭게 사용하세요.
    // 수정 필요
    while(1){
        printf("수행하고자 하는 번호를 입력하세요: (1:최솟값 출력, 2:최댓값 출력, 3:누적값 출력: 4:배열 정렬, 5: 종료)\n");
        scanf("%d", &num);
        if(num == 5){
            printf("프로그램을 종료합니다.\n");
            break;
        } else if(num == 1){
            min_point(arrayPtr);
        } else if(num == 2){
            max_point(arrayPtr);
        } else if(num == 3){
            sum_point(arrayPtr);
        } else if(num == 4){
            align_array(arrayPtr);
        } else{
             printf("다시 입력하세요.\n\n");
        }
    }
       
    return 0;
}

#1. (5점) 점의 좌표(x,y)를 멤버로 가지는 POINT 구조체를 선언한다.

=> 배웠던대로 typedef struct를 이용해 선언하면 된다.

응용도 아니고 배웠던 걸 그대로 써보는 문제였기 때문에 최소한 5점은 받으라고 주었던 문제

#2. (10점) x좌표가 최솟값을 가지는 (x,y)를 출력하는 min_point 함수를 작성한다.

=> for 문 1개 + POINT 구조체 변수만으로도 짤 수 있던 문제.

나는 상당히 코드짜는걸 귀찮아해서 미리 짜놓았던 align_array의 코드를 복붙한 뒤 부등호같은 것만 바꿔 썼기 때문에 2중 for문을 쓰게 되었다.

#3. (10점) y좌표가 최댓값을 가지는 (x,y)를 출력하는 max_point 함수를 작성한다.

=>역시 for 문 1개 + POINT 구조체 변수만으로도 짤 수 있던 문제.

마찬가지로 나는 상당히 코드짜는걸 귀찮아해서 미리 짜놓았던 align_array의 코드를 복붙한 뒤 부등호같은 것만 바꿔 썼기 때문에 2중 for문을 쓰게 되었다.

#4. (10점) x,y좌표의 누적 좌표값 (x,y)을 출력하는 sum_point 함수를 작성한다.

=> x, y를 0으로 초기화시킨 새 POINT 변수를 하나 만들고, 거기에 그냥 for문으로 모두 더해주면 됐던 문제.

#5. (10점) 두 점의 좌표를 맞바꾸는 swap_point 함수를 작성한다.

=>두 POINT 구조체를 스왑해야 하는 어렵지 않았던 문제. 새 POINT 변수를 만들어 바꾸면 해결.

그런데 얘를 왜 5번으로 줬는지 이해가 안됐다.

global function으로 선언을 하고 싶었으면 아예 맨 위로 올렸어야지. 이렇게 문제를 짜게 되면 swap_point가 선언되지 않았기 때문에 min_point, max_point, sum_point에서 swap_point를 사용할 수 없다.(아마 다른 문제에서 스왑을 사용하려고 했다면 warning: implict declaration of function, 또는 previous implicit declaration is here 에러가 뜰 것이다.) 그래놓고선 HINT: swap_point 사용 (반드시 사용해야 하는 것은 아님) 이라고 적어놨다.

#6. (20점) 주어진 구조체 배열에 대하여 x좌표를 기준으로 오름차순(작은 값부터 큰 값 순서로 정렬)으로 정렬하는 align_array 함수를 작성한다.

=>그냥 위에서도 썼던 2중 for문으로 버블정렬을 수행하면 됐던 문제.

코드를 짰던 순서가 align_array->min/max_point->swap_point->sum_point였어서 굳이 기존에 썼던 코드들을 지우고 swap_point를 써야 했나 싶었다. 그래서 그냥 쭉 2중 for문으로 해결함.

(버블정렬의 시간복잡도는 O(n^2)이지만, 요소가 많지도 않고 c는 빠르니까 그냥 넘어가도록 하자.)

#7. (5점) 구조체 배열의 크기(좌표의 갯수)는 상수로 고정시키지 않고 array_size라는 전역변수로 정의하며 sizeof 함수를 이용하여 구한다. (채점 시, 좌표의 갯수 및 좌표값을 변경하여 채점할 예정)

=>각 자료형의 크기를 알고 있었다면 풀만했던 문제.

int 2개를 썼으므로 4바이트 * 2개 = 8바이트. 즉, array_size = sizeof(구조체 배열) / 8을 하거나, sizeof(구조체 배열) / sizeof(POINT)를 하면 됐다.

#8. (30점) 메인함수에서 다음 입력을 받아 조건에 맞게 수행하도록 구현하세요.

=>위 모든 함수들을 모두 구현해야 30점을 받을 수 있던 문제.

내가 기억하기로 저기서도 일부 부분점수가 있던거로 기억한다. 그러니까, 모든 함수를 제대로 구현하면 30점. 일부만 제대로 구현하면 30점에서 깎이는 느낌.

나는 while->if를 썼는데, while->switch를 쓴 친구도 있었다.


솔직히 c가 좀 재미없긴 하다...

이번 과목 끝나면 c에 손도 안댈듯.(대신 c++을 하겠지.)

'일상' 카테고리의 다른 글

요즘 근황  (0) 2024.01.17
[꼰] 소프트웨어학과 신입생들 성적장학금 꿀팁  (2) 2022.10.11
백준 골드 티어 달성  (0) 2022.06.07