7월 7일 [3일차] 알고리즘 코딩 테스트(31번~50번)

마틴·2023년 7월 8일

📙 학습 문제

💡 조건문, 반복문, 문자열, 정렬

  1. 숨어있는 숫자의 덧셈(1)
    • 문수
  2. 문자열 안에 문자열
    • strstr()
  3. 제곱수 판별하기
    • sqrt()
  4. 세균 증식
  5. 대문자와 소문자
    • 문문
  6. 암호 해독
    • 문문
  7. 가위 바위 보
    • 문문
  8. 개미 군단
  9. 주사위의 개수
  10. n의 배수 고르기
  11. 문자열 정렬하기(1)
    • 문수지만, 문문으로 풀기
  12. 가장 큰 수 찾기
  13. 외계행성의 나이
    • 수수지만, 문수로 풀기
  14. 배열 회전시키기
    • 왼쪽 1칸, 오른쪽 1칸 ➡️ 오른쪽 (배열크기-1)칸, 오른쪽 1칸
  15. 인덱스 바꾸기
  16. 숫자 찾기
  17. 369게임
  18. 약수 구하기
  19. 피자 나눠 먹기(2)
  20. 합성수 찾기

🏆 오늘의 미션


☢️ 풀이예시 - 먼저 풀어보고 나서 참고하기 🐸

  • 숨어 있는 숫자의 덧셈

    (문수) : 문자열을 주고, 숫자로 리턴하는 문제

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

int solution(const char* my_string) {
    int answer = 0;
    
    for(int i = 0;    ; i++) {  // 굳이 문자열의 길이를 구할 필요가 없다.
        char c = my_string[i];
        if(c == 0) break;
        if(c >= '0' && c <= '9') answer += c -'0';
    }
    return answer;
}
  • 대문자와 소문자

    (문문) : 문자열을 주고, 문자열로 리턴하는 문제

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

char* solution(const char* my_string) {
    int l = strlen(my_string);	// '문문'유형은 문자열의 길이를 구해서 answer를 동적할당 해야 한다.
    char* answer = (char*)calloc(l+1, sizeof(char));  // malloc보다 calloc을... NULL문자 공간 하나 추가
    
    for(int i =0;   ; i++) {
        char c = my_string[i];  // if문에서 많이 쓰일 것이니깐, c로 줄여서 쓰자.
        if(c == 0) break;  // 문자열 끝났으면 for문 탈출
        if(c >= 'A' && c <= 'Z') answer[i] = c - 'A' + 'a' ;
        else if(c >= 'a' && c <= 'z') answer[i] = c - 'a' + 'A';
    }
    
    return answer;
}
  • 암호해독

    (문문) : 문자열을 주고, 문자열로 리턴하는 문제

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

char* solution(const char* cipher, int code) {
    int l = strlen(cipher);	// '문문'유형은 자열의 길이를 구해서 answer를 동적할당해야 한다.
    char* answer = (char*)calloc(l+1, sizeof(char));  // malloc보다 calloc을... NULL문자 공간 하나 추가
    int countA = 0;  // 읽는 문자열(cipher)은 i 인덱스로 기억하고, 쓰는 문자열(answer)는 countA로 기억한다.
    
    for(int i=0;  ; i++) {
        char c = cipher[i];  // if문에서 많이 쓰일 것이니깐, c로 줄여서 쓰자.
        if(c == 0) break;  // 문자열 끝났으면 for문 탈출
        if( (i+1) % code == 0 ) answer[countA++] = cipher[i];
    }
    return answer;
}
  • 가위바위보 (손가락의 개수! 2-0-5)

    (문문) : 문자열을 주고, 문자열로 리턴하는 문제

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

char* solution(const char* rsp) {
    int l = strlen(rsp);  // '문문'유형은 자열의 길이를 구해서 answer 동적할당을 해야 한다.
    char* answer = (char*)calloc(l+1, sizeof(char));  // malloc보다 calloc을... // NULL문자 공간 하나 추가
    
    for(int i=0;  ; i++) {
        char c = rsp[i];   // if문에서 많이 쓰일 것이니깐, c로 줄여서 쓰자.
        if(c == 0) break;  // 문자열 끝났으면 for문 탈출
        switch(c) {
            case '2' : answer[i] = '0'; break;
            case '0' : answer[i] = '5'; break;
            case '5' : answer[i] = '2'; break;
        }
    }
    
    return answer;
}
  • 문자열 정렬하기(1)

    (문문) : 문수 문제이지만, 숫자배열을 리턴해야하므로, 문문 유형으로 보면 됨.

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

int compare(int *a, int *b) {  // qsort 쓸거니깐 compare 함수 간단히 만들어주기
    return *a - *b;
}

int* solution(const char* my_string) {
    int l = strlen(my_string);   // answer 배열의 원소 개수를 대략 짐작하려면 my_string 길이 필요
    int* answer = (int*)calloc(l, sizeof(int));  // malloc보다 calloc을...
    int countA=0;  // answer배열에 몇개난 쓸지 따로 카운트해야 함
    
    for(int i=0;   ; i++) {
        char c = my_string[i]; 	// 여러번 쓸거니깐 변수 c를 만들어서 간단하게 씁시다.
        if (c == 0) break;   // 문자열 끝나면 for문 탈출
        if (c >= '0' && c <= '9') answer[countA++] = c - '0';
    }

    qsort(answer, countA, sizeof(int), compare);  // 정렬하기.  qsort(배열이름, 배열원소 개수, 원소 하나당 크기, compare);

    return answer;
}
  • 가장 큰 수 찾기
  • 외계행성의 나이 (수수로 풀어도 되지만, 문수로 푸는 것이 쉬움)

    (문수) : 문자열을 주고, 숫자로 리턴하는 문제

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

char* solution(int age) {
    char* answer = (char*)calloc(4, sizeof(char));  // 숫자를 문자로 바꿀려고 준비
    char strAge[4] = "";
    sprintf(strAge, "%d", age);  // 숫자를 문자로 바꿀때엔  sprintf(문자열, "%d", 변수명)
    
    for(int i=0;   ; i++) {  // 종료조건은 내부에서 따로 체크하니 여기서는 생략
        char c = strAge[i];   // 많이 쓰일 것이니깐, c로 줄여서 쓰자.
        if(c == 0) break;   // 문자열 끝났으면 for문 탈출
        answer[i] = c - '0' + 'a';
    }
    return answer;
}
  • 배열 회전시키기 (첫번째 방법)
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

int* solution(int numbers[], size_t numbers_len, const char* direction) {
    int* answer = (int*)calloc(numbers_len, sizeof(int));
    int lor;
    if(direction[0] == 'r' ) lor = 1;
    else lor = -1;
    
    for(int i=0; i<numbers_len; i++) {
        int p = i+lor;
        
        if(p == -1) p = numbers_len-1;
        else if(p == numbers_len) p = 0;
        
        answer[p] = numbers[i];
    }
    
    return answer;
}
  • 배열 회전시키기 (두번째 방법)

    right는 오른쪽으로 한칸씩, left는 왼쪽으로 한칸이 아니라 오른쪽으로 (배열크기-1)만큼씩 옮기면 됨

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

int* solution(int numbers[], size_t numbers_len, const char* direction) {
    int* answer = (int*)calloc(numbers_len, sizeof(int));
    int lor;
    if(direction[0] == 'r' ) lor = 1;
    else lor = numbers_len-1;
    
    for(int i=0; i<numbers_len; i++) {
        int p = (i+lor) % numbers_len;
        answer[p] = numbers[i];
    }
    
    return answer;
}
  • 인덱스 바꾸기
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

char* solution(const char* my_string, int num1, int num2) {
    int l = strlen(my_string);
    char* answer = (char*)calloc(l+1, sizeof(char));
    strcpy(answer, my_string);   // 문자열 복사하고, 해당 자리 바꿔주기, temp변수는 필요없음
    answer[num1] = my_string[num2];
    answer[num2] = my_string[num1];

    return answer;
}
  • 피자 나눠먹기
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

int solution(int n) {
    int answer = 1;
    while (1) {
        if( (answer * 6) % n == 0 ) break;
        answer++;
    }

    return answer;
}
  • 합성수 찾기

    소수 찾기 문제와 쌍둥이 문제

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

int solution(int n) {
    int answer = 0;
    
    for(int i=1; i<=n; i++) {
        for(int j=2; j < i; j++) {
            if(i % j == 0) {
                answer++;
                break;
            }
        }
    }
    return answer;
}

  • 3진법 뒤집기 (첫번째 방법)
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

int solution(int n) {
    long long answer = 0;
    long long input = n;
	
    // 주어진 수의 뒷자리부터 3진법으로 잘라내고 거꾸로 숫자를 만든다
    for( ; input ; input/=3) answer = answer * 10 + (input % 3);

    input = answer;  answer = 0;

	// 거꾸로 된 숫자를 반대로 뒤집는다(10진수지만 3진수라고 생각해야 함)
    for( ; input ; input/=10) answer = answer * 10 + (input % 10);

    input = answer;  answer = 0;

	// 뒷자리부터 3진법으로 잘라내서 10진수로 변경한다.
    for( ; input ; input/=10) answer = answer * 3 + (input % 10);
 
    return answer;
}
  • 3진법 뒤집기 (두번째 방법)
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

int solution(int n) {
    long long answer = 0;
    long long input = n;
    
    // 주어진 수의 뒷자리부터 3진법으로 잘라내고, 잘라낸 숫자를 3진법으로 누적한다.
    for( ; input ; input/=3) answer = answer * 3 + (input % 3);

    return answer;
}
  • 가장 큰 수
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

// 자리수에 상관없이 큰 숫자가 앞에와야 큰수가 만들어진다.
// 정수를 문자로 만들어서 ab로 붙인것과 ba로 붙인 것을 비교한다.
int compare(int *a, int *b) {
    char *strAB = (char *)calloc(10, sizeof(char));
    char *strBA = (char *)calloc(10, sizeof(char));
    sprintf(strAB, "%d%d", *a, *b);
    sprintf(strBA, "%d%d", *b, *a);
    return strcmp(strBA, strAB);
}

// numbers_len은 배열 numbers의 길이입니다.
char* solution(int numbers[], size_t numbers_len) {
    char* answer = (char*)calloc(numbers_len * 4 + 1, sizeof(char));
    answer[0] = 0;
    
    // 붙였을 때, 큰 수가되는 순서로 정렬(sorting)한다.
    qsort(numbers, numbers_len, sizeof(int), compare);
    
    for(int i=0; i<numbers_len; i++) {
        char str[5];
        sprintf(str, "%d", numbers[i]);
        strcat(answer, str);
        if(numbers[0] == 0) break;
    } // 쭉 이어붙인다.
    
    return answer;
}
  • 메뉴 리뉴얼
#include <string>
#include <vector>
#include <set>         // set과 multiset 사용
#include <algorithm>   // prev_permutation 사용

using namespace std;

vector<string> solution(vector<string> orders, vector<int> course) {
	vector<string> answer;
	set<string> newMenu;
	multiset<string> chosenMenu;

	for (auto order : orders) {
		for (auto c : course) {
			if (order.length() < c) continue;
			
            // c개의 조합을 만들어내기 위한 임시 int 벡터
            vector<int> temp;
			for (int i = 0; i < order.length(); i++) {
				if (i < c) temp.push_back(1);
				else temp.push_back(0);
			}
            
            // 모든 종류의 조합 만들기 : prev_permutation 사용
			do {
				string str = "";
				for (int i = 0; i < order.length(); i++) 
					if (temp[i] == 1) str += order[i];

				// 알파벳순으로 정렬하고, 이용한 메뉴에 추가한다.
                // chosenMenu가 multiset이라서 중복 추가 가능. count함수로 갯수확인 가능
                sort(str.begin(), str.end());   
				chosenMenu.insert(str);
			} while (prev_permutation(temp.begin(), temp.end()));
		}
	}

	for (auto c : course) {
		int max = 0;
		for (auto str : chosenMenu)
			if (str.length() == c && chosenMenu.count(str) > max) max = chosenMenu.count(str);
		
		for (auto str : chosenMenu)
			if (str.length() == c && chosenMenu.count(str) == max && max > 1) newMenu.insert(str);
	}
	answer = vector<string>(newMenu.begin(), newMenu.end());

	return answer;
}
profile
목원대 컴퓨터공학과

0개의 댓글