목록C (37)
궤도
문제 풀이 이 문제는 한가지만 떠올리면 난이도가 아주 낮아진다. 바로 테두리를 두르는 것이다. 이렇게 말이다. 왜냐면 왼쪽 그대로 입력을 받아 문제를 풀면 테두리에 있는 지역을 계산하기 위한 함수를 따로 만들어야 한다. 하지만 오른쪽으로 입력을 받으면 어느 지점을 골라도 해당 지역을 중심으로 한 3x3 사각형이 있으니 함수를 하나만 써도 된다. 이것도 character이니 입력을 받을 때 공백(엔터)를 처리해 줄 empty 변수를 잊지 말자. *인 부분은 그대로 출력하고 -인 부분에 대해서는 fidZ 함수를 호출한다. 좌표가 (x, y)일 때 해당 좌표를 중심으로 한 3x3 사각형의 좌표는 (x-1~x+1, y-1~y+1)이므로 해당 부분을 탐색하며 지뢰의 수를 계산한다. 물론 나 자신을 세는 경우를 빼..
문제 풀이 문제가 좀 길지만 잘 읽어보면 어려운 문제는 아니다. 일단 반복문이 언제 끝날지 모르니 while loop를 사용했다. 모든 자릿수의 수가 나와야 반복문이 끝날테니 각 자릿수의 출현 여부를 체크하는 bool 배열도 만들고 이 배열의 모든 값이 true인지 확인하는 함수도 만들었다. 여기까지 했다면 나머지는 쉽다. isAll 함수로 반복문을 탈출할 수 있는지 체크하며 숫자 A를 쪼개가며 digit 배열을 갱신한다. 코드에서의 i가 문제에서의 n이 되는 셈인데 마지막에 i++를 해주기 때문에 이미 모든 자릿수가 나온 상태에서도 무조건 i를 하나 더 증가하게 된다. 그러니 마지막 출력에서 빼준다. 소스코드 #define _CRT_SECURE_NO_WARNINGS #include #include bo..
문제 풀이 이 문제에서 가장 중요한건 두가지이다. 하나는 중복을 제거하는 것이고 남은 하나는 c가 가장 긴 변이 되도록 하는 것이다. i와 j를 이용해 a와 b변의 길이를 정하고 총 길이 n에서 이 둘을 뺀 값이 c가 되도록 한다. 반복문을 보면 알겠지만 i
문제 풀이 그리디 알고리즘의 대표적인 문제이다. 해당 문제가 그리디 알고리즘으로 풀릴 수 있는 조건은 잔돈이 서로 배수관계여야 한다는 것이다. 예를 들어 잔돈이 10원, 7원, 1원이고 거스름돈이 14원이라면 7원 2개가 optimal choice지만, 그리디 알고리즘은 10원 1개, 1원 4개 총 5개를 지불해야 한다는 결과를 내놓는다. 다시 문제로 돌아가면, 해당 잔돈들을 coins 배열에 저장하고 가장 큰 잔돈부터 대입해보며 동전의 수를 더해나간다. 더이상 지불해야 할 거스름돈이 없는 경우에도 의미없이 반복문이 돌아가는 경우를 막고자 조건을 하나 더 추가했다. 소스코드 #define _CRT_SECURE_NO_WARNINGS #include int main() { int coins[6] = { 50..
문제 풀이 입력이 숫자니까 int로 받아야한다는 생각에서 벗어나면 금방 풀린다. 숫자를 문자열로 받고 각 자릿수에 접근하기 쉽다는 문자열의 특성을 이용해 양끝에서부터 비교하면 된다. 홀짝을 나눌 필요는 없다. 코드를 보면 알겠지만 가운데 숫자라면 자기자신과 비교하게 된다. 일치하지 않는 부분을 발견하는 순간 isPal을 false로 바꿔주고 반복문을 빠져나오면 된다. 소스코드 #define _CRT_SECURE_NO_WARNINGS #include #include #include int main() { char num[101]; bool isPal = true; scanf("%s", &num); int length = strlen(num); for (int i = 0; i < length / 2; i++..
문제 풀이 이번에 정답일 경우 얻게될 점수를 저장하는 tmp_score와 얻은 점수의 총합을 저장할 sum 변수가 필요하다. tmp_score는 처음에 0으로 초기화하고 O라면 하나 증가하고 X라면 0으로 다시 초기화 한다. O일 경우 tmp_score를 증가함과 동시에 그 결과를 sum에 바로 더해준다. 소스코드 #define _CRT_SECURE_NO_WARNINGS #include #include int main() { char score[1001]; int tmp_score = 0, sum = 0; scanf("%s", &score); for (int i = 0; i < strlen(score); i++) { if (score[i] == 'O') { //O면 현재 스코어를 증가하고 sum에 합침 ..
문제 풀이 a, b를 입력받고 둘 사이의 최대 공약수를 구하는 문제이다. 원래는 유클리드 호제법을 사용하는게 정석이겠지만...난 너무 귀찮았다. a b) { //a가 더 작도록 int tmp = a; a = b; b = tmp; } if (b % a == 0) //a가 최대공약수인지 확인해보고 printf("%d\n", a); else { for (int i = a / 2; i >= 1; i--) { //a 나누기 2 부터 검사 if (b % i == 0 && a % i == 0) { printf("%d\n", i); break; } } } }
문제 풀이 재귀함수를 배울 때 꼭 나오는 하노이탑이다. 자매품으로는 피보나치 수열이 있다. 보통은 이동 횟수를 계산하게 하는 경우가 많은데 이건 어떤 원판이 어떻게 이동했는지까지 출력해야 한다. 귀찮아보이지만 어려운 일은 아니다. 하노이탑에 대한 설명은 널리고 널렸지만 굳이 내가 또 적어보겠다...n개의 원판을 A에서 C로 옮기고 싶다면 먼저 위에 쌓인 (n-1)개의 원판을 A에서 B로 옮긴다. 그리고 n번째 원판을 A에서 C로 옮기고 남은 (n-1)개의 원판을 B에서 C로 옮기면 된다. 상황에 따라 source, tmp, dest 인자를 서로 옮겨가며 재귀함수를 호출하고 출력하면 된다. 아무리 생각해도 나보다 친절하게 설명한 다른 블로그가 많을 것 같다. 소스코드 #define _CRT_SECURE_N..