https://school.programmers.co.kr/learn/courses/30/lessons/250137?language=c
 
소요 시간: 약 53분
체감 난도: ★★☆☆
사용 언어: C
 

문제

 
 
풀이

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

int solution(int bandage[], size_t bandage_len, 
             int health, 
             int** attacks, size_t attacks_rows, size_t attacks_cols)
{
    int answer = 0;
    
    const int t = bandage[0];
    const int x = bandage[1];
    const int y = bandage[2];
    
    int suc_time = 0;
    int cur_time = 0;
    int cur_h = health;
    
    int attack_i = 0;
    while( cur_time <= attacks[attacks_rows-1][0] )
    {
        if (cur_time == attacks[attack_i][0])
        {   suc_time = 0;
            cur_h -= attacks[attack_i][1];
            attack_i++;
         
            if (cur_h <= 0) return -1;
        }
        
        else{
            suc_time++;
            if (suc_time == t) { suc_time = 0; cur_h += (x + y); }
            else { cur_h += x; }
        }
        
        if (cur_h > health) cur_h = health;
        
        printf("%d: %d\n", cur_time, cur_h);
        
        cur_time++;
    }
    
    answer = cur_h;
    
    return answer;
}

 
확실히 나름대로의 계획?을 세우니 좀 더 수월했던 것 같다. 전에 풀던 거여서 그런 걸지도 모르겠지만 아무튼 그러하다. 근데 풀고나니 시간은 꽤 지나있던,,, 시간을 정수로 생각하려니 헷갈리기도 했고, suc_time을 증가하는 걸 빼먹기도 했다.

더보기

//붕대 감는 시간 t초: 1~50
//회복 체력 x: 1~100
//추가 체력 y: 1~100
//-> bandage

//연속 여부 - 공격 여부

//최대 체력 health: 1~1000

//피해량: 1~100
//공격 시간: 1~1000
//->attacks: 1~100

//사망 여부 dead -> -1 return

//체력 업데이트 - 연속 점검/붕대 감기 완료 점검
//사망 점검
//몬스터 공격 점검

 

라는 나름의 계획,,,

 
다른 사람의 풀이를 보는데 조건 연산자를 너무 잘 사용하셔서 신기했다! 그 분은 for문을 사용하셨는데, 그 편이 더 합리적인 것 같았다.
 
다음부턴 변수를 더 적게 사용하는 방향으로 풀어봐야겠다.
 


 

https://school.programmers.co.kr/learn/courses/30/lessons/258712

 

소요 시간: 1시간 14분 26초

체감 난도: ★★★☆☆

사용 언어: C

 

문제

 

 

풀이 (막장으로 풀었지만 일단 풀어서 기분이 좋다. ㅎㅎ)

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

void set_zero(int* array, int array_len) {	// 배열의 모든 원소를 0으로 초기화
    for (int i=0; i<array_len; i++) { array[i]=0; }
}

char** friend_name(char* names, char* giveTake[]) {	// 문자열에서 친구의 이름을 구한다.
    char* give = NULL;
    char* take = NULL;
    
    give = strtok(names, " ");
    take = strtok(NULL, " ");
    
    giveTake[0] = give;	// 선물을 준 친구
    giveTake[1] = take;	// 선물을 받은 친구
    return giveTake;
}

int solution(const char* friends[], size_t friends_len, char* gifts[], size_t gifts_len) {
    int answer = 0;
    
    int i, j, k;
    
    char* giveTake[2];	// 문자열에서 구한 친구의 이름을 넣을 함수
    
    int give_take[friends_len][friends_len];	// 한 친구가 특정 친구에게 준 선물의 개수
    int expectation[friends_len];	// 다음 달에 받게 될 선물의 개수
    
    int given[friends_len];	// 이번 달에 준 선물의 개수
    int taken[friends_len];	// 이번 달에 받은 선물의 개수
    
    // 배열을 0으로 초기화
    for (i=0;i<friends_len;i++) {set_zero(give_take[i], friends_len);}
    set_zero(expectation, friends_len);
    set_zero(given, friends_len);
    set_zero(taken, friends_len);
    
    for (i=0; i<gifts_len; i++) {	
        char** name;
        name = friend_name(gifts[i], giveTake);
        
        for(j=0; j<friends; j++) { int cmp = strcmp(name[0], friends[j]); if (!cmp){break;} }
        for(k=0; k<friends; k++) { int cmp = strcmp(name[1], friends[k]); if (!cmp){break;} }
        
        give_take[j][k]++;
        given[j]++;	// j번째 친구는 선물을 주었다.
        taken[k]++;	// k번째 친구는 선물을 받았다.
    }
    
    for (i=0; i<friends_len; i++) {
        for (j=i+1; j<friends_len; j++) {
            int dif = give_take[i][j] - give_take[j][i];	// 서로에게 준 선물 개수의 차이
            
            if (dif > 0) {expectation[i]++;}	// i번째 친구가 선물을 더 많이 준 경우
            else if (dif < 0) {expectation[j]++;}	// j번째 친구가 선물을 더 많이 준 경우
            else {	// 준 선물의 개수가 같은 경우
                int friend1 = given[i] - taken[i];	// i 번째 친구의 선물 지수
                int friend2 = given[j] - taken[j];	// j 번째 친구의 선물 지수
                if (friend1 > friend2) { expectation[i]++; }	// i 번째 친구의 선물 지수가 더 큰 경우
                else if (friend1 < friend2) { expectation[j]++; }	// j 번째 친구의 선물 지수가 더 큰 경우
                // 두 친구의 선물 지수가 같은 경우 다음 달 선물을 받는 친구가 없다.
            }
        }
    }
    
    answer = expectation[0];	// 다음 달 받을 선물의 개수가 가장 많은 친구
    for (i=1; i<friends_len; i++) {
        printf("%d\n", expectation[i]);
        if ( answer < expectation[i] ) { answer = expectation[i]; }
    }
    
    return answer;
}

 

 

문제 밑의 입출력 예시를 많이 참고해서 풀었다. 

 

 

 

찾아본 개념/함수

  • 문자를 기준으로 문자열 나누기: char * strtok(char * str, const char * delim);
    동작: 첫 번째 호출에서, 첫 번째 파라미터에 분할할 문자열을 가리키는 포인터를 전달한다.(문자열 상수를 넣는 것은 좋지 않다)
    이후 str 내에서 delim에 해당하는 문자를 찾는다. 문자를 찾으면 \0으로 치환한 후, 첫 번째 토큰의 주소값을 반환한다. 이후 같은 문자열을 분할하고 싶으면 첫 번째 인수에 NULL을 넣게 되는데, 그래야 마지막으로 탐색한 위치부터 분할을 시작한다.

    예를 들어 다음 코드에서 첫 번째 출력값은 str 배열의 a의 주소값, 두 번째 출력값은 e의 주소값, 세 번째 출력값은 h의 주소값이다.
char str[] = "abcd efg hijk";
char *token = strtok(str, " ");

while (token != NULL)
{
	printf("%p", token);
	token = strtok(NULL, " ");
}

 

  • 문자열 비교: int strcmp(const char* str1, const char* str2);
    동작: 두 문자열을 한 문자씩 아스키값으로 비교한다. 두 문자열이 같으면 0이 반환된다. 두 문자열이 다르면, 처음으로 다른 값을 갖게되는 두 문자의 아스키값의 대소를 비교한다. str1의 아스키값이 더 크면 양수가, str2의 아스키값이 더 크면 음수가 반환된다.

 

개선사항

문제를 너무 계획없이 푸는 것 같긴 함! 대충이라도 전체적인 틀을 생각해보고 풀기. 안 그럼 더 오래걸리고 쉽게 실수하는 것 같다.

그리고 포인터 쓰는데 자꾸 실수 함..! char**형 넣어야 되는데 char*형 넣는 등등,, 배열이랑 포인터 사용에 유의하기

 

 

 

 

https://dojang.io/mod/page/view.php?id=376%EF%BB%BF#google_vignette

 

C 언어 코딩 도장: 45.1 문자를 기준으로 문자열 자르기

45 문자열 자르기 지금까지 문자열을 복사하거나 붙이는 방법을 알아보았습니다. 이번에는 주어진 문자열을 자르는 방법을 알아보겠습니다. 참고로 문자열 자르기는 포인터를 이용하는 방식이

dojang.io

 

https://blockdmask.tistory.com/391

 

[C언어/C++] strcmp, strncmp 함수(문자열 비교)에 대해서

안녕하세요 BlockDMask입니다.오늘은 c/c++에서 두개의 문자열이 같은지, 다른지 다르면 어떤식으로 다른지 검사할 수 있는 strcmp 함수. 문자열 비교 함수인 strcmp 함수를 알아 보려고 합니다. 오늘은

blockdmask.tistory.com

 

 


 

+ Recent posts