ipwn
C) 코드업 함수문제 풀이 본문
codeup1602.절대값 구하기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include<stdio.h> double absolutevalue(double n1) { if (n1 < 0) { return n1*-1; } else { return n1; } } int main() { double a; scanf("%lf", &a); printf("%.10g", absolutevalue(a)); return 0; } | cs |
절대값은 0에서부터 그 수 까지의 거리이므로 양수일때는 그냥 그 수 자체가
자신의 절대값이 되는 것이고, 음수는 자신에게 곱하기 -1 을 해 주면 그 수가 절대값이
되는 것 입니다. double형 변수 a를 n1에 대입한 뒤 n1이 양수일때는
n1을 반환하고 음수일 때는 n1에 -1을 곱한 수를 반환해주는 코드입니다.
codeup1610. 서브스트링
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include<stdio.h> int i; char Str[500]; char *mysubstr(char* str, int start, int end) { for (i = 0; i < end; ++i) { Str[i] = str[i + start]; } return Str; } int main() { int start, end; char str[500]; scanf("%s %d %d", str, &start, &end); printf("%s", mysubstr(str, start, end)); return 0; } | cs |
Str이라는 전역 변수를 만들어 놓고 반복문을 실행시켜
Str문자열에 문자를 하나하나 대입해 준 뒤 문자열로 반환시켜서
그 반환된 문자열만 출력해주는 코드입니다.
codeup1615.셀프넘버
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #include<stdio.h> #define ar 5031 int arr[ar];//전역 변수는 자동으로 0을 대입함 int mysn(int start) {//자기 자신+자기의 자리수를 다 더해주는 함수 int s = start; while (start) { s += start % 10; start /= 10; } return s; } int main() { int start, end; int sum = 0; scanf("%d %d", &start, &end); for (int i = 1; i <= end; ++i) {//1부터 end까지 셀프넘버가 아닌 경우 그 배열에 1 대입 arr[mysn(i)] = 1; } for (int j = start; j <= end; ++j) {//start부터 end까지 배열에 대입된 수가 0인경우 if (!arr[j])sum += j;//sum에 그 순서만큼 sum += j } printf("%d", sum); return 0; } |
일단 이 문제를 이해하려면 셀프넘버를 이해 해야 하는데요,
셀프넘버란?
어떤 자연수 n이 있을 때, d(n)을 n의 각 자릿수 숫자들과
n 자신을 더한 숫자라고 정의하자.
예를 들어 d(91) = 9 + 1 + 91 = 101 이 때, n을 d(n)의
제네레이터(generator)라고 한다.
위의 예에서 91은 101의 제네레이터이다.
어떤 숫자들은 하나 이상의 제네레이터를 가지고 있는데,
101의 제네레이터는 91 뿐 아니라 100도 있다.
그런데 반대로, 제네레이터가 없는 숫자들도 있으며,
이런 숫자를 인도의 수학자 Kaprekar가 셀프 넘버(self-number)라 이름 붙였다.
예를 들어 1,3,5,7,9,20,31 은 셀프 넘버 들이다.
이 코드는 각 수들의 mysn(제네레이터)를 구한 뒤 그 숫자 크기의 순서의 배열에
1을 대입해 주고 배열에 대입된 수들이 0인것만 start부터 end까지
다 더해서 출력해주는 코드입니다.
ar에 5031을 대입 한 이유는
mysn(4999)는 5030의 값이 나오기 때문입니다. (오버플로우 예방)
mysn에 의한 반환은 1부터 end까지 하는데요 그 이유는
대입의 시작을 start부터 해버리면 1이 아닌 다른 수가 왔을 때
(1<start 인 경우)1일때는 arr[2]번째 순서의 배열에1을 대입하는데
더 큰 숫자부터 시작하면 대입이 기본적으로 arr[2]에는
1이 대입되지를 않기 때문입니다.
하다가 심심해서 재귀함수로 옮겨보았습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #include<stdio.h>//함수 +재귀 #define ar 6000 int arr[ar]; int sum = 0; int mysn(int); int put(int, int); int total(int, int); int main() { int start, end; int sum1; int i = 1; scanf("%d %d", &start, &end); put(i, end); sum1 = total(start, end); printf("%d", sum1); } int mysn(int i) {//각 자리수를 더해줄 함수 int s = i; while (i) { s += i % 10; i /= 10; } return s; } int put(int i, int end) {//mysn 함수에서 반환된 수의 순서의 if (i > end) return 0;//배열에 1 대입 함 재귀함수라서 대입하는 else {//숫자의 양이 커지면 에러가 나버림 arr[mysn(i)] = 1; return put(i + 1, end); } } int total(int start, int end) {//start부터 end까지 배열에 대입된 if (start > end) return sum; //수가 1이 아닌 순서일 때는 (sum+=그 배열의 순서) else { if (!arr[start]) sum += start; return total(start + 1, end); } } | cs |
역시 시험기간엔 뭘 해도 재밌는 것 같습니다.
codeup1620.자리수끼리의 합(재귀함수)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #include<stdio.h> int sum = 0; int sum1; int jari(int input) { if (input == 0) { sum1 = sum; sum = 0; return sum1; } else { sum += input % 10; return jari(input / 10); } } int main() { int input, total; scanf("%d", &input); total = jari(input); if (total >= 10) { total = jari(total); } printf("%d", jari(total)); return 0; } | cs |
이 코드는 각 자리수를 계속 더해주면서 한자리수가
나올 때 까지 계속 더하는 코드입니다.
먼저 수를 입력받아서 각 자리수를 sum에 계속 더해준 후에 마지막엔
sum1에 sum을 대입 한 후 sum1으로 숫자를 반환해 주는 코드인데요,
이렇게 짠 이유는 마지막에 반환되는 sum1은 두 자리수일 가능성이
농후하기 떄문입니다. 그렇기 때문에 아래 메인함수 부분에서는
jari함수에서 반환 된 값을 total변수에 저장한 뒤
다시 total의 값이 10이 넘어가면 jari함수로 넘겨주고 한 번 더
jari를 돌았을 경우에도 10의 자리수일 경우도 있기 때문에 한번더
jari 함수로 보낸 뒤 검사를 한 다음 마지막에 반환 된 그 값을 출력하게 됩니다.
codeup1904.a와 b사이의 홀수 모두 출력(재귀함수)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include<stdio.h> int h(int n1, int n2) { if (n1 > n2) { return 0; } else if (n1 % 2 == 1) { printf("%d ", n1); return h(n1 + 1, n2); } else if (n1 % 2 == 0) { return h(n1 + 1, n2); } } int main() { int a, b; scanf("%d %d", &a, &b); h(a, b); return 0; } | cs |
말 그대로 a와 b를 입력받아서 홀수를 출력해주는 코드인데,
a와 b의 값을 입력받고 a를 n1에 대입, b를 n2에 대입 한 뒤
n1을 계속 1씩 늘려서 반환해가며 n1이 홀수일 경우 n1을 출력하고
아닐경우 n1을1씩 늘리기만 하는 그리고 n1이 n2보다 커질 경우는
0으로 반환 되어 종료를 하게 되는 코드입니다.
codeup1920. 2진수 변환(재귀함수)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include<stdio.h> int i = 0; int two(int n1, int n2[10000]) { if (n1 == 0) { if (i == 0) return 0; i--; printf("%d", n2[i]); return two(n1, n2); } else { if (n1 % 2 == 0) { n2[i] = 0; ++i; } else if (n1 % 2 == 1) { n2[i] = 1; ++i; } return two(n1 / 2, n2); } } int main() { int n1; int n2[10000] = { 0, }; scanf("%d", &n1); two(n1, n2); if (n1 == 0) { printf("%d", n1); } return 0; } | cs |
이 코드는 입력받은 10진수를 2진수로 변환해 출력하는 코드를
재귀함수로 구현한 것 입니다.
먼저 n1을 입력받아서 재귀함수로 올려준 뒤에
n2라는 순서대로 배열에 하나씩 n1을 2로 나눈 나머지값을 넣어주면서
n1을 2로 나눠가며 n1이 0이되는순간 n2라는 배열에 있는 숫자들을
다시 역순으로 출력하는 코드입니다.
codeup1928.우박수(재귀함수)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include<stdio.h> int myub(int n1) { if (n1 == 1) { printf("%d\n", n1); return 1; } else if (n1 % 2 == 0) { printf("%d\n", n1); return myub(n1 / 2); } else if (n1 % 2 == 1) { printf("%d\n", n1); return myub(n1 * 3 + 1); } } int main() { int a; scanf("%d", &a); myub(a); return 0; } | cs |
우박수란 홀수를 입력받으면 입력받은수 * 3 + 1 을 해 주고 짝수일 경우는
/ 2 를 해 준뒤 각각의 그 수가 짝수면 / 2 홀수면 * 3 + 1 을 계속 반복해서
1이 될 때 까지 반복하는 것 입니다.
이 것은 그 우박수들을 구하는 코드를 재귀함수로 구현 한 것 인데,
먼저 a를 입력받고 n1에 대입 한 뒤 n1이 홀수일 경우는 n1 * 3 + 1 을 반환 해주고
짝수일 경우는 n1 / 2를 반환해가면서 1로 반환 될 때 까지
계속 반복 출력하는 코드입니다.
codeup1953.삼각형 별 찍기(재귀함수)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include<stdio.h> int starh(int n) { if (n == 0) { return 0; } else { printf("*"); return starh(n - 1); } } int output(int star, int line) { if (star > line) { return 0; } else { starh(star); printf("\n"); return output(star + 1, line); } } int main() { int input, star = 1; scanf("%d", &input); output(star, input); return 0; } | cs |
이 코드는 반복문의 이해를 위한 공부를 할 때 배웠던 별찍기를
재귀함수로 구현해 낸 코드입니다. 이 코드의 동작 방식은 맨 처음 별을 몇개 찍을지
starh함수로 정하는데, n에 대입 된 값 만큼별을 출력할 것 임을 의미 합니다.
그리고 output함수에서는 줄을 띄우고 완벽한 출력을 하게 되는데요,
메인 함수 부분의 star은 output함수의 star변수에 대입되고,
input변수는 line변수에 대입이 됩니다.
맨 처음 star의 값은 1이므로 starh 함수로 올라가서
별을 한개 찍어내고 줄을 띄우고 star을 1 늘려 반환을 한 뒤
두번째에는 별을 두개 찍어낸 뒤 줄을 띄우고 다시
star을 1 늘려서 반한하는 결과를 반복해서
star이 line보다 커지는 경우는 output함수를 탈출하게 되고 마지막에는
결국 line개의 줄을 띄우고 line개 만큼의 별을 출력되게 합니다.
'Programming' 카테고리의 다른 글
[memory] 메모리 구조 (0) | 2018.01.08 |
---|---|
C) 포인터, 문자와 문자열 처리 함수, 구조체 (0) | 2017.12.27 |
C) swap 함수 구현 (0) | 2017.12.18 |
C) 포인터 (0) | 2017.12.18 |
C) strlen, strcmp, strcpy 함수 조사 및 구현 (0) | 2017.12.18 |