정보 AP

코드업 2636 : 먹느냐 먹히느냐

Halfand 2023. 5. 11. 23:29

 

문제

2636 : 먹느냐 먹히느냐

깊은 바다 아래에는 A와 B라는 두 종류의 생물이 있습니다.
A는 B의 포식자이지만, A는 크기가 B보다 큰 경우에만 B를 먹습니다.
예를 들어, A종의 크기 = {8, 1, 7, 3, 1}이고, B종의 크기 = {3, 6, 1}이면, A가 B를 먹는 쌍은 7쌍이 있습니다.
( A>B: 8-3, 8-6, 8-1, 7-3, 7-6, 7-1, 3-1 )

A종과 B종의 각 유기체의 크기가 주어졌을 때, A가 B를 먹을 수 있는 쌍이 몇개인지 세는 프로그램을 작성하시오.

 

 

입력

첫째 줄에 테스트케이스의 개수 T가 입력된다.
각 케이스의 첫째 줄에는 A와 B의 크기인 N, M이 입력된다.
N(1 ≤ N ≤ 20,000),  M(1 ≤ M ≤ 20,000)
둘째 줄에는 A의 데이터가 공백으로 분리되어 N개 입력된다.
셋째 줄에는 B의 데이터가 공백으로 분리되어 M개 입력된다.

출력

A가 B보다 큰 AB쌍의 수를 각각 출력한다.

 

입력 예시

2
5 3
8 1 7 3 1
3 6 1
3 4
2 13 7
103 11 290 215

 

출력 예시

7
1

 


MY CODE

#include <stdio.h>
int main()
{
    int t, n, m, s;
    scanf("%d", &t);
    int ss[t];
    for(int o=0; o<t; o++){
      s=0;
      scanf("%d%d", &n, &m);
      int nn[n]; //n만큼의 배열 설정
      int mm[m]; //m만큼의 배열 설정
      for(int i=0; i<n; i++){
        scanf("%d", &nn[i]); //각 배열 요소 받기
      }
      for(int i=0; i<m; i++){
        scanf("%d", &mm[i]); //각 배열 요소 받기
      }
      for(int i=0; i<n; i++){
        for(int j=0; j<m; j++){
            nn[i]>mm[j]? s++:s; //크기 비교하기
        }
      }
      ss[o]=s; //결과 저장하기
    }
    for(int i=0; i<t; i++){
      printf("%d\n", ss[i]); //결과 출력하기
    }
    return 0;
}

 

코드설명

int nn[n]; //n만큼의 배열 설정
int mm[m]; //m만큼의 배열 설정
for(int i=0; i<n; i++){
  scanf("%d", &nn[i]); //각 배열 요소 받기
}
for(int i=0; i<m; i++){
  scanf("%d", &mm[i]); //각 배열 요소 받기
}
for(int i=0; i<n; i++){
  for(int j=0; j<m; j++){
    nn[i]>mm[j]? s++:s; //크기 비교하기 
  }
}
ss[o]=s; //결과 저장하기

 


생겼던 문제점

사실 제 코드가 많이 비효율적이고 예쁘지 않습니다. 근데 왜 이렇게 생겼냐 하면... 

 

사실 맨 처음 짰던 코드는 이것이었습니다. 

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int t, n, m, s;
    int *nn, *mm, *ss;
    
    scanf("%d", &t);
    ss=(int *)calloc(t, sizeof(int));
    for(int o=0; o<t; o++){
      s=0;
      scanf("%d%d", &n, &m);
    
      nn=(int *)calloc(t, sizeof(int)); //배열을 20000*20000으로 설정하기에는 낭비가 너무 심하기 때문에 
      mm=(int *)calloc(t, sizeof(int)); //calloc함수를 이용하여 동적할당하였음
      
      for(int i=0; i<n; i++){
        scanf("%d", &nn[i]);
      }
      for(int i=0; i<m; i++){
        scanf("%d", &mm[i]);
      }
      for(int i=0; i<n; i++){
        for(int j=0; j<m; j++){
            nn[i]>mm[j]? s++:s;
        }
      }
      ss[o]=s;
      //printf("%d", s);
      
    }
    for(int i=0; i<t; i++){
      printf("%d\n", ss[i]);
    }
    free(nn);
    free(mm);
    free(ss);
    return 0;
}

 

 

제가 기억하기로는 배열 크기의 선언으로는 변수가 안 되는 것으로 알고 있었고, 실제로 맨 처음 코드를 짜다가 그로 인해 문제가 생겨서 calloc을 사용했습니다. 사실 동적 할당 사용하는데 신나서 비효율적인 코드임에도 그냥 돌렸습니다...

 

근데 이 코드가 Dev c++이나 Replit같은 컴파일러에서는 돌아가면서 코드업에만 입력하면 실행 중 에러가 뜨면서 안 돌아가더라고요.

 

주변 지인들에게까지 물어봤으나 결국 해결하지 못하고 원인을 모르고 있다가... 머리나 식힐 겸 이 포스팅을 쓰기 시작했습니다. 

 

그때까지는 초기의 코드를 쓰고 있었기 때문에 왜 동적할당을 사용하였는지 예시를 들어 설명하려고 아래 코드를 작성하였습니다. 

#include <stdio.h>
int main(){
	int n;
	scanf("%d",&n);
	int arr1[100];
	int arr2[n];
}

 

 

위에 작성한 코드는 올바른 코드의 예시이고, 이제 변수를 배열의 크기로 선언하여 잘못된 예시를 만들려고 할 때 갑자기 위화감이 느껴졌습니다.

아니... 변수는 배열 크기로 선언이 안 된다면서 왜 됐지.......?

 

생각해보면 이미 변수를 scanf로 받았기 때문이지 않을까 생각하고 있는데, 그렇다면 처음에 배열 크기를 변수로 선언했을때 왜 안 된지는 아직도 모르겠습니다........

 

 

그러나 굴러만 가면 되기 때문에 굳이 손대지 않기로 했습니다^^ㅎㅎㅎㅎㅎㅎ

 

 


순서도

 


코드업도 안 하는 게으른 인간이라 정말 오랜만에 c언어를 만지다 보니 기억이 안 나는게 많아 또 한참 헤맸습니다. 감 잃지 않으려면 꾸준하게 풀어야 할 것 같아요. 

 

문제는 아래에 있습니다. 꼭 한번 본인의 힘으로 풀어보시길!

https://codeup.kr/problem.php?id=2636&rid=23688

 

먹느냐 먹히느냐

깊은 바다 아래에는 A와 B라는 두 종류의 생물이 있습니다. A는 B의 포식자이지만, A는 크기가 B보다 큰 경우에만 B를 먹습니다. 예를 들어, A종의 크기 = {8, 1, 7, 3, 1}이고, B종의 크기 = {3, 6, 1}이면

codeup.kr