부스트코스 - 모두를 위한 컴퓨터 과학 (CS50 2019) - 4주차 Mission
업데이트:
✔︎ 미션 1.
1. 미션 제목
해당 코스에서 문제를 챌린저들을 위한것이기때문에 공개하면 안된다고 공지되어있어서 문제 내용은 제거합니다.
#include <stdio.h>
#define MAX 5
#define TRUE 1
#define FALSE 0
void selectSort(int *arr);
void bubbleSort(int *arr);
void mergeSort(int *arr, int start, int end);
void swap(int x, int y, int tmp, int *arr);
void compare(int *x, int *y);
void merge(int *arr, int start, int mid, int end);
int selectSort_1[MAX] = {1, 2, 3, 4, 5};
int selectSort_2[MAX] = {5, 4, 3, 0, 1};
int bubbleSort_1[MAX] = {1, 4, 2, 5, 8};
int bubbleSort_2[MAX] = {2, 5, 4, 3, 1};
int recursive_1[MAX] = {1, 1, 1, 3, 2};
int recursive_2[MAX] = {2, 1, 1, 3, 1};
int mergeSortResult[MAX]; // 병합정렬된 배열이 들어갈 변수
int main(void) {
selectSort(selectSort_1);
selectSort(selectSort_2);
bubbleSort(bubbleSort_1);
bubbleSort(bubbleSort_2);
mergeSort(recursive_1, 0, MAX - 1); // 배열데이터와함께 시작 과 끝 인텍스값을 넘기기때문에 MAX - 1 을 넘겨줍니다.
mergeSort(recursive_2, 0, MAX - 1);
compare(selectSort_1, selectSort_2);
compare(bubbleSort_1, bubbleSort_2);
compare(recursive_1, recursive_2);
return 0;
}
void selectSort(int *arr) {
// 선택정렬
// n개의 배열중 가장 작은값을 찾아 0부터 n-1 번째까지 반복문 돌면서 0번 인덱스부터 스왑
for (int i = 0; i < MAX - 1; i++) {
int minIndex = i;
int tmp;
for (int j = i + 1; j < MAX; j++) {
if (arr[minIndex] > arr[j]) {
minIndex = j;
}
}
if (i != minIndex) { // 자기 자신이 최소값일때 swap 하지않음
swap(i, minIndex, tmp, arr);
}
}
}
void bubbleSort(int *arr) {
// 버블정렬
// n 개의 배열을 돌면서 n 과 n + 1 의 값을 비교하여 n + 1 이 더 작다면 swap
// 정렬이 진행될때마다 제일 오른쪽 배열부터는 더이상 비교할 필요가 없어 그만큼 비교횟수를 -1 해줘야한다.
int tmp;
for(int i = 0; i < MAX -1; i ++) {
for (int j = 0; j < MAX - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
swap(j, j + 1, tmp, arr);
}
}
}
}
void mergeSort(int *arr, int start, int end) {
// 재귀정렬
if (start < end) {
int mid = (start + end) / 2;
// printf("mid: %d\n", mid);
mergeSort(arr, start, mid); // 배열의 처음부터 중간까지
mergeSort(arr, mid + 1, end); // 배열의 중간 다음배열부터 마지막 배열까지
merge(arr, start, mid, end); // mergeSort 의 실행이 모두 끝나야 merge 함수실행
}
}
// 기타 사용 함수
void swap(int x, int y, int tmp, int *arr) {
tmp = arr[x];
arr[x] = arr[y];
arr[y] = tmp;
}
void compare(int *x, int *y) {
int result;
for (int i = 0; i < MAX; i++) {
if (x[i] != y[i]) {
result = FALSE;
break;
} else {
result = TRUE;
}
}
printf("입력값: %d%d%d%d%d, %d%d%d%d%d ", x[0], x[1], x[2], x[3], x[4], y[0], y[1], y[2], y[3], y[4]);
printf("출력값: %s\n", result == 0 ? "False" : "True");
}
void merge(int *arr, int start, int mid, int end) {
int i = start;
int j = mid + 1;
int k = start; // 정렬된 배열을 담을 변수의 index
// printf("mid :%d start: %d end: %d\n", mid, start, end);
while(i <= mid && j <= end) {
if (arr[i] <= arr[j]) { // 앞의 값보다 뒤의값이 크거나 같은지
mergeSortResult[k] = arr[i];
i++;
} else { // 뒤에비교하는 숫자가 더 작을경우
mergeSortResult[k] = arr[j];
j++;
}
k++;
}
if (i > mid) { // while 문에서 배열에 할당하지 못한 나머지 값을 여기서 할당한다.
for(int t = j; t <= end; t++) {
mergeSortResult[k] = arr[t];
k++;
}
} else {
for(int t = i; t <= mid; t++) {
mergeSortResult[k] = arr[t];
k++;
}
}
for (int t = start; t <= end; t++) { // 정렬된 배열을 원래 배열에 넣는다.
arr[t] = mergeSortResult[t];
}
}
✔︎ 미션 2.
해당 코스에서 문제를 챌린저들을 위한것이기때문에 공개하면 안된다고 공지되어있어서 문제 내용은 제거합니다.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// #include <math.h>
#define TRUE 1
#define FALSE 0
// 요구사항 자체가 거리를 예시로들면서 정해진 순서대로 숫자가 입력된다고 보았습니다.
// 요구사항에는 없는 정렬코드가 들어가게되면 불필요한 로직이 생기고 불필요한 실행시간이 소요되기때문에 순수하게 거리의 센터위치를 구현하는데 중점을 두었습니다.
// 정렬 관련된 문제가 아닌것같아서 저는 모든 값은 이미 정렬된 순서대로 들어온다고 가정하고 코드를 작성하였습니다.
// 입력된 배열 내에서 센터에 가장 근접한 값을 찾아 리턴하는 문제라고 이해하고 접근하였습니다.
int inputData_1[4] = {0, 4, 6, 9};
int inputData_2[4] = {2, 2, 2, 4};
int inputData_3[6] = {1, 2, 3, 5, 7, 9};
int inputData_4[6] = {1, 2, 10, 23, 31, 35};
// void getIntArrSize(int *arr);
void findCenterHouse(int arr[], int count);
int averageDistance(int arr[], int count);
int main(void) {
clock_t start, end;
double result;
start = clock(); //시간 측정 시작
findCenterHouse(inputData_1, sizeof(inputData_1) / sizeof(int));
findCenterHouse(inputData_2, sizeof(inputData_2) / sizeof(int));
findCenterHouse(inputData_3, sizeof(inputData_3) / sizeof(int));
findCenterHouse(inputData_4, sizeof(inputData_4) / sizeof(int));
end = clock(); //시간 측정 끝
result = (double)(end - start);
printf("실행시간: %.0f\n", result);
return 0;
}
void findCenterHouse(int arr[], int count) {
int average = averageDistance(arr, count);
int isCenterHouse = FALSE;
for (int i = 0; i < count; i++) { // 평균 지점과 일치하는 값이 배열에 있을때
if(arr[i] == average) {
isCenterHouse = average;
break;
}
}
if (isCenterHouse == FALSE) { // 평균 지점과 일치하는 센터값이 배열에 없을때
int maxOfSmallValue; // 평균값보다 작은값중에 가장 큰값
int minOfBigValue; // 평균값보다 큰값중에 가장 작은값
for(int i = 0; i < count; i++) { // 센터값과 가장 근사치에있는 양쪽의 값을 구함
if (average > arr[i]) {
// printf("평균값보다 작은 배열의 값: %d\n", arr[i]);
maxOfSmallValue = arr[i];
} else {
// printf("평균값보다 큰 배열의 값: %d\n", arr[i]);
minOfBigValue = arr[i];
break;
}
}
// printf("a: %d\n", a);
// printf("b: %d\n", b);
// 선택값과 근사치로 있는 양쪽의 값을 구했으면
// 근사치에서 가장 작은값을 빼고 가장 큰 값에서 큰사치를 뺴서 양쪽 거리의 격차값이 더 작은쪽이 센터
if (abs((maxOfSmallValue - arr[0]) - (arr[count - 1] - maxOfSmallValue)) < abs((minOfBigValue - arr[0]) - (arr[count - 1] - minOfBigValue))) {
isCenterHouse = maxOfSmallValue;
} else {
isCenterHouse = minOfBigValue;
}
}
printf("Center House: %d\n", isCenterHouse);
}
int averageDistance(int arr[], int count) { // 평균 거리를 갖는 지역의 정수를 반환
int sum = 0;
int average = 0;
for (int i = 0; i < count; i++) {
sum += arr[i];
}
average = sum / count;
// printf("Averrage Distance: %d\n", average);
return average;
}
✔︎ 미션 3.
해당 코스에서 문제를 챌린저들을 위한것이기때문에 공개하면 안된다고 공지되어있어서 문제 내용은 제거합니다.
// 아직 해결 중....
✔︎ 미션 4 (난이도 최상).
해당 코스에서 문제를 챌린저들을 위한것이기때문에 공개하면 안된다고 공지되어있어서 문제 내용은 제거합니다.
#include <stdio.h>
#define HORIZONTAL 9
#define VERTICAL 8 // 세로길이는 별로 의미가 없네요?
/*
문제에서 원하는 출력값은 낙차값중에 가장 큰값입니다.
따라서 개별 박스의 낙차를 구하기보다는 해당 열에있는 박스중 가장 낙차값이 크게 나오는 숫자를
resultArr 배열에 저장하고
그리고 이 배열에서 가장 큰 값을 출력하는 방식으로 생각하고 코드를 작성했습니다.
90도 회전 어쩌구하는건 일단 무시했습니다.
*/
int dropTheBox[HORIZONTAL] = {7, 4, 2, 0, 0, 6, 0, 7, 0};
int resultArr[HORIZONTAL];
void vertical_drop(int dropTheBox[], int horizontal);
int main(void) {
vertical_drop(dropTheBox, HORIZONTAL);
int max = 0;
printf("result array: ");
for (int i = 0; i < HORIZONTAL; i++) { // 낙차값 배열중 가장 큰 값을 추출하는 코드 입니다.
printf("%d ", resultArr[i]);
if (max < resultArr[i]) {
max = resultArr[i];
}
}
printf("\n");
printf("result: %d", max);
return 0;
}
void vertical_drop(int dropTheBox[], int horizontal) {
for (int i = 0; i < horizontal; i++) {
int countMax = 0; // countMax 는 비교하려는 값(dropTheBox[i]) 보다 같거나 큰값이 몇개나 있는지 얻어오는 변수입니다.
for (int j = i; j < horizontal; j++) { // 비교하려는 값보다 큰값들을 찾습니다.
if (dropTheBox[i] <= dropTheBox[j] && dropTheBox[i] != 0) {
countMax += 1;
}
}
if (dropTheBox[i] == 0) { // arr[i] 가 0일경우 resultArr에 그대로 0을 넣어줍니다.
resultArr[i] = 0;
} else {
// horizontal 은 90도 회전했을경우 떨어질 높이값이 됩니다.
// 그래서 낙차값을 총 높이 - 아래박스가 현재 박스보다 크거나 같은 박스의 갯수 - 그리고 떨어질때마다 +1씩 낙차값이 올라가는데 자기 자신이 위치한 칸은 제외해야 하므로 i 를 빼줍니다.
resultArr[i] = horizontal - countMax - i;
}
}
}
댓글남기기