목록C (37)
궤도
문제 풀이 그냥 수학문제다. 왜 입력받은 n에서 1을 뺐냐면 15, 30과 같은 경우 때문이다. 이런 숫자는 15로 나누어 떨어지기 때문에 방 안에서의 번호를 계산하기 어려워진다. 그래서 계산 전에 1을 빼고 계산 후에 1을 다시 더해준 것이다. 소스코드 #define _CRT_SECURE_NO_WARNINGS #include int main() { //그냥 수학 int n; scanf("%d", &n); n--; printf("%d %d\n", n / 15 + 1, n % 15 + 1); }
문제 풀이 재귀함수를 금방 떠올린다면 쉬울 문제이다. 여기서 가장 중요한 것은 오른쪽 괄호가 들어갈 조건이다. 왼쪽 괄호가 2개 나온 상태에서 오른쪽 괄호가 3개 들어갈 순 없다. 왼쪽 괄호는 몇개가 나와도 상관없지만, 오른쪽 괄호의 출현 가능 여부는 왼쪽 괄호의 수가 결정한다. 사용할 수 있는 왼쪽 괄호와 오른쪽 괄호는 각각 n개 이다. 우리의 목표는 총 2n개의 괄호를 전부 사용하는 것이다. 그러므로 일단 재귀를 끝내는 조건은 남은 왼쪽, 오른쪽 괄호의 수가 모두 0개여야 한다는 것이다. 그렇지 않은 경우에는 어떤 상황이 있을까? 1. 왼쪽 괄호를 전부 사용하고 오른쪽 괄호만 남은 상황 (left == 0) 2. 남은 왼쪽 괄호의 수가 남은 오른쪽 괄호의 수보다 적은 경우 (left < right) ..
문제 풀이 머리를 엄청 쓴 것 치곤 코드가 짧게 나오는 문제이다. 코드의 2/3 정도가 입력받은 문자를 가공하는 과정이고, 이마저도 switch가 아니라 문자열 배열을 사용했으면 훨씬 짧아졌을 것이다. 문제를 따라 해야할 일을 차근차근 해보자. 먼저 암호화할 메세지를 입력받고, 해당 메세지의 길이가 7의 배수인지 확인한다. 7의 배수가 아니라면 7의 배수가 될 때까지 알파벳을 순서대로 뒤에 붙여준다. 많이 붙여봤자 6개라 switch를 썼는데 이렇게 축소할 수 있다. char concat_arr[7] = "abcdef"; for(int i = 0; i < concat_cnt; i++) m_arr[length++] = concat_arr[i]; 실제로 돌려보지 않아서 문법오류가 있을 수도 있는데 논리는 맞..
문제 풀이 전혀 어렵지 않은 문제지만, 문제를 잘못 읽는 바람에 뻘짓을 좀 심하게 했다. 실제 시험이었다면 큰일이었을 것이다. 입력 예를 보면 첫 줄에 입력되는 것은 앞으로 입력될 숫자의 개수이다. 난 저것마저 평균계산에 포함해야 하는 것이라고 착각해서 고생했다. 손으로 몇번씩 계산해봐도 답이 나오지 않았는데, 당연할 뿐이다. 먼저 입력된 숫자 배열을 오름차순으로 정렬한다. 그리고 가장 작은 수부터 묶어서 연쇄적으로 평균을 구해주면 된다. 배열에 숫자가 1개만 있을 수도 있는 경우를 고려해주자. 소스코드 #define _CRT_SECURE_NO_WARNINGS #include void insertion_sort(int arr[], int length) { //오름차순 삽입정렬 for (int i = 1;..
문제 풀이 접근을 잘못했던 문제. 하필이면 그 접근으로도 입력 예시는 전부 다 맞게 나와서 난 그게 맞는 줄 알았다. 근데 혹시나 하는 마음에 돌려본 테스트 케이스에서 오류를 발견했다. 먼저 기본틀을 설명하고 잘못됐던 풀이와 옳은 풀이를 설명하겠다. 일단 수를 입력받은 뒤 자릿수대로 쪼개어서 정수 배열에 집어넣었다. 1의 자리부터 집어 넣으니 뒤집혀서 저장될 것이다. 입력 예3의 경우라면 {1,1,7,7,2}가 저장됐을 것이다. 만약 입력 예2라면 {0,3,3}일 것이다. 보면 알겠지만 해당 배열이 감소 수열이 아니라면 문제의 조건을 만족하는 수는 없다. 난 처음에 이렇게 접근했다. 왼쪽부터 탐색하며 감소 수열이 되는 순간 양 옆의 수를 swap하고 그 swap 지점의 왼쪽 부분이 내림차순이 되도록 정렬..
문제 풀이 이 문제가 쉬워 보일 수 있지만 함정이 하나 있다. 바로 차량 끝번호가 묶인 규칙이다. 각각 5씩 더한 모습인데 5+5=10이니까 끝자리만 가져오기 위해 10으로 나눈 나머지를 가져와야 한다. 사실 엄청난 함정은 아니고 내가 문제를 대충 읽는 바람에 허둥거렸다. 소스코드 #define _CRT_SECURE_NO_WARNINGS #include int main() { int date, s_date, n; int car_arr[101]; int cnt = 0; scanf("%d %d", &date, &n); for (int i = 0; i < n; i++) scanf("%d", &car_arr[i]); date %= 10; //끝자리만 가져옴 s_date = (date + 5) % 10; //da..
문제 풀이 난 별찍는 문제가 싫다. 별별 기상천외한 방법으로 별을 찍고, 대부분 노가다성이 짙은 문제라 풀고나서의 성취감도 그닥없다. 그래도 이걸 풀어야 졸업을 시켜줄테니 풀어야 한다. 다이아몬드 모양에 집중하지 말고 마지막 별까지의 공간(?)을 세보자 위 예시에선 3-4-5-4-3이다 공백은 2-1-0-1-2 이다. 가운데를 기준으로 잘라서 출력해야할 것 같다는 기분이 들 것이다. 가장 윗줄의 공백 갯수는 n/2개 이다. 여기부터 한 개씩 줄어들 것이고 별은 1부터 시작해서 두 개씩 늘어날 것이다. 이를 고려해서 윗 부분을 출력했다면 이제 반대로 공백을 한 개씩 늘리고, 별은 두 개씩 늘리며 아랫 부분을 출력한다. 별찍기는 재미 없어서 풀이도 대충 쓰게 된다. 소스코드 #define _CRT_SECUR..
문제 풀이 문제의 길이만큼이나 까다로웠다. 규칙은 간단하다. 1. 첫글자가 단축키가 될 수 있는지 확인 2. 두 개의 단어로 이루어졌다면 두번째 단어의 첫글자가 단축키가 될 수 있는지 확인 3. 위 과정에서 단축키를 얻지 못했다면 나머지 글자를 앞에서부터 탐색하며 단축키가 될 수 있는지 확인 그러니 조건문도 이 순서로 작성해야 한다. 우선 입력부터 받아보자. menu 구조체를 사용했는데 여기에는 각 메뉴(이름)와, 단축키의 위치, 그리고 해당 메뉴가 2개 이상의 단어로 이루어졌는지 체크하는 변수들이 존재한다. 단축키의 위치를 나타내는 key_pos는 1000으로 초기화 한다. 1000개 이상의 글자로 이루어진 메뉴가 들어올 일은 없겠지? 공백을 포함해서 입력을 받아야 하니 gets를 사용한다. 그리고 들..