본문 바로가기
지난 학기들의 기록/C 기초

[C실습] 배열 유형 분석 1- N개의 정수배열에서 M개씩 그룹지어 비교하기(+추가)

by 아메리카노와떡볶이 2020. 5. 31.
728x90
배열 유형 분석 1. N개의 정수배열에서 그룹을 만들어 비교하기

 

이번 포스트에서는 배열 유형 중 N개의 정수가 저장된 배열에서 M개씩 값들을 묶어서 최대,최솟값, 오름차순 ,내림차순 정렬등의 유형을 공부해보는 시간을 가지겠습니다.

 

N=2, 2개씩 그룹묶기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#pragma warning(disable:4996)
#include <stdio.h>
/* 문제1번 토너먼트 ㅜ*/
int main() {
    int N,max=0,i=0,k=0;
    int gradeN[100= { 0 };//출전자들의 성적을 담을 배열선언
    int error_cnt = 0;// 에러발생시 확인을 위한 카운트 변수
    //입력파트
    scanf("%d"&N);//출전자의 수를 입력받습니다
    for (i = 0; i < N; i++) {
        scanf("%d"&gradeN[i]);
    }// 출전자들의 성적을 입력받습니다
 
    //출전자들의 점수가 범위안에 있는지 확인합니다.
    for (int i = 0; i < N; i++) {
        if (gradeN[i] > 100 || gradeN[i] < 0) {
            error_cnt++// 0점보다 작거나 100점보다 높은 점수이면 에러카운트 1추가
            printf("ERROR");
            break;
        }
    }
    
    //토너먼트 실행 파트
    while(N>1&&error_cnt==0){ // N이 1보다클때, N은 배열의 크기이고 반복마다 줄어든다
        int k = 0;
        for (int i = 0; i < N; i = i + 2) {//2개씩 묶은 그룹의 시작점 i= 0 , 2 ,4 ,6 . . .
            max = gradeN[i]; // 각 그룹의 첫번째원소를 최댓값으로 지정합니다
            
            for (int p = i + 1; p < i + 2 && p < N; p++) {
                if (gradeN[p] > max) max = gradeN[p];
            }// 그룹의 최댓값을 max변수에 넣어줍니다.
 
            gradeN[k] = max;// 다음 라운드로 진행될 최댓값들을 0번인덱스부터 차례로 넣습니다.
            k++;
        }
 
        if (N % 2 == 1) N = N / 2 + 1;// 만약 홀수이면 부전승이 생기므로 N=N/2+1 입니다.
        else N = N / 2;//짝수이면 그대로 N을 2로 나눕니다.
 
        //라운드마다 출력파트
        for (int j = 0; j < N; j++printf(" %d", gradeN[j]);
     printf("\n");
    }
    return 0;
}
cs

 

N=3, 3개씩 묶기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#pragma warning(disable:4996)
#include <stdio.h>
/*문제 4번 N개의 정수중 가장 큰 수,가장 작은 수가 남을때까지 반복출력하기*/
int main() {
    int max_ar[20], min_ar[20];// 최댓값 ,최솟값 배열 선언
    int N,j;
    scanf("%d"&N);
    for (int i = 0; i < N; i++) {
        scanf("%d"&max_ar[i]);
    }//max배열 입력받기
    for (int i = 0; i < N; i++) {
        min_ar[i] = max_ar[i];
    } // min배열과 max배열 초기화
 
    for (int i = N - 1; i >= 0; i--) {
        printf(" %d", max_ar[i]);
    }// 배열에 저장한수를 거꾸로 출력하기
    printf("\n");
    int max = 0, min = 9999;
    if (N == 1printf("%d\n%d", max_ar[0], min_ar[0]);
    while (N > 1) { //N이 1보다 클때, N은 배열의 크기이고 반복마다 줄어든다.
        int k = 0;
 
        for (int i = 0; i < N; i =i+ 3) {    // i가 N보다 작을 경우 
아래를 반복하면서 3씩 더해간다.
            max = max_ar[i];//i일때를 최댓값 max 으로 설정합니다
            min = min_ar[i];//i일때를 최솟값 min 으로 설정합니다.
            
 
            for (int p = i + 1; p < i + 3 && p < N; p++) {  //i+1부터 시작하여 
3단위씩 arr2의 최댓값과 arr1의 최솟값을 구한다.
                if (max_ar[p] > max) max = max_ar[p];
                if (min_ar[p] <min) min = min_ar[p];
            }
            max_ar[k] = max;      //3단위씩 묶어 구한 최댓값을 max2에 차례로 저장한다.
            min_ar[k] = min;      //3단위씩 묶어 구한 최솟값을 min1에 차례로 저장한다.
            k++;
        }
 
        if (N % 3 == 0) { // 배열의 크기 N을 3으로 나누어떨어질때와
 아닐때를 구분하여 구합니다.
            N = N / 3;
        }
        else N = N / 3 + 1;
            
        // 저장된 배열 출력파트
        for (j = 0; j < N; j++printf(" %d", max_ar[j]);

        printf("\n");
        for (j = 0; j < N; j++printf(" %d", min_ar[j]);
        printf("\n");
        
    }
 
 
    return 0;
}
cs

 

========================================================심화학습

두 문제를 풀이하면서 느낀 것은 두개의 문제가 같은 유형이라고 생각했습니다.

배열에서 N개씩 그룹을 묶어서 최댓값이나 최솟값등을 찾고 그것을 출력하는 과정을 반복하는 유형입니다. 

위의 문제들을 일반화하여 N개에서 M개 그룹묶기 로 지정하고

일반화한 문제를 품으로써 이 유형에 익숙해지도록 해보겠습니다.

[문제1]. N개의 정수를 입력받고 그 정수들을 M개씩 그룹지어서 최댓값을 출력합니다.

그리고 마지막 최댓값이 나올때까지 반복합니다.

 

[입력예시1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

                  5

 

[출력예시1] 5 10 15 20

                 20

 

[입력예시2] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

                  2

 

[출력예시2] 2 4 6 8 10 12 14 16 18 20

                  4 8 12 16 20

                  8 16 20

                  16 20

                  20

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#pragma warning(disable:4996)
#include <stdio.h>
/* N개의 정수를 입력받고 M개씩 묶어서 최댓값을 반복출력하라*/
int main() {
    
    int num_array[100];
    int N, M,k=0,max=0;
    scanf("%d %d"&N, &M);//N은 배열의 크기, M개씩 묶음
    
    //입력파트
    for (int i = 0; i < N; i++) {
        scanf("%d"&num_array[i]);
    }
 
    while (N > 1) {
        k = 0;
        for (int i = 0; i < N; i = i + M) {
 
            max = num_array[i];
            for (int p = i + 1; p<N&&< i + M; p++) {
 
                if (num_array[p] > max) max = num_array[p];
            }
 
            num_array[k] = max;
            k++;
        }
        if (N % M == 0) N = N / M;
        else N = N / M + 1;
 
        for(int j=0;j<N;j++){
            printf("%d ", num_array[j]);
        }
        puts("");
        
    }
    return 0;
}
cs

[문제2]. N개의 정수를 입력받고 그 정수들을 M개씩 그룹지은 후 내림차순으로 출력합니다.

 

입력예시 10 3

            12 13 14 15 16 17 18 19 20 21
출력예시     

            41 31 21 71 61 51 91 81 2 12   

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#pragma warning(disable:4996)
#include <stdio.h>
/*양의 정수 N개를 입력받아 각각 역순을 구한 후
M개씩 나누어서 감소하는 순으로 정렬하라*/
 
int main()
{
    int N,M;
    int ar[100];
    int reversed_ar[100= { 0 };
    scanf("%d %d"&N,&M);
    for (int k = 0; k < N; k++) {
        scanf("%d"&ar[k]);
    }
    for (int k = 0; k < N; k++) {
        reversed_ar[k] = reversed_num(ar[k]);
    }
 
    //M개씩 내림차순 정렬하기
 
    for (int i = 0; i < N; i = i + M) {// i=0 ,3,6,9 . . . 
 
        //i가 3의 배수일때마다 그때부터 3개씩 묶어서 내림차순 정렬하기
        for (int t = 0; t < M; t++) {
            for (int p = i; p < i + M - t-1; p++) {
                if (reversed_ar[p] < reversed_ar[p + 1]) {
                    int temp = reversed_ar[p];
                    reversed_ar[p] = reversed_ar[p + 1];
                    reversed_ar[p + 1= temp;
                }
            }
        }
        for (int k = i; k < i + M && k < N; k++) {
            printf("%d ", reversed_ar[k]);
        }
    }
 
    return 0;
}
 
int reversed_num(int N) {
 
    int a = 0, b = 0, c = 0;
 
    while (N > 0) {
        a = N % 10;
        N = N / 10;
        c = c * 10 + a;
    }
    return c;
}
cs

 

 

 

728x90

댓글