다음의 코드의 결과를 알아맞춰야 하는 문제이다.

구조체와 포인터의 이해가 필요한 문제이다

답:  6

 

답이 6으로 나오게 된 이유를 처음에는 다음과 같이 생각했다 (조금 틀린 생각이니 너무 자세히는 보지 말자).

(영어로 되어 있는 이유는 stackoverflow에 올리기 위해서 적은 부분이니, 이 부분은 감안해서 보면 된다.)

 

1. Due to struct node, num 3, 5, 6 are set into a, b, c in the num variable.

   (struct node에 의해 num 3, 5, 6은 각각 a, b, c에 할당된다)

2. *ptr points the start address of num due to struct node *ptr = # which means that it points to the address of the index = 0 which is 3 in {3, 5, 6}.

   (*ptr는 num의 시작주소를 가리키기 때문에 0번 index를 가르키므로 *(int)ptr 은 3을 출력할 것이다.)

3. Therefore,  printf("%d\n", *ptr); prints 3,

   (따라서, 만약 printf("%d\n", *ptr);가 있다면, 3이 출력이 될 것이고)

4. printf("%d\n", *((int*)ptr + 1 + (3-2))); is printing *(0+1+1) which is index = 2 of num which equals to 6.

   (printf("%d\n", *((int*)ptr + 1 + (3-2)));는 결국 *(0 + 1 + 1)이 되므로 2번 index인 6이 출력된다.)


이걸 이제 제대로 구조체를 사용해서 설명해야한다. 위의 index는 array(배열)에 사용하는 것이므로, 틀리기 때문에, 다음과 같이 설명해야 제대로 된 설명이라고 할 수 있다.

(다음 답변은 stackoverflow의 친절한 어느 답변자가 내 생각을 더 정확히 바꿔 설명해준 것이다)

1. Due to the initializer, 3, 5, 6 are set into a, b, c in the num variable.

   (3, 5, 6은 초기화되어 a, b, c의 num 변수에 할당된다)

2. *ptr points to the start address of num due to struct node *ptr = #, which is the same as the address of num.a.

   (*ptr = #에 의해 *ptr는 num의 시작주소를 가르키고, 이는 num.a의 주소와 똑같다.)

3. Therefore, printf("%d\n", *ptr); prints 3.

   (따라서, printf("%d\n", *ptr);가 있다면, 3이 출력된다)

4. (int*)ptr yields a pointer to num.a with the proper type.

   ((int*)ptr는 num.a를 int*로 type casting을 한다.)

5. Adding 2 to ptr means that we add the size of two ints to the address. Note that the typecast is very important, as we would've otherwise added the size of two struct nodes to the address; the effect of adding to a pointer depends on the pointer type.

   (ptr+2는 주소에 int size를 2개 더한다는 뜻이다. 참고로, typecast는 굉장히 중요하다. 그렇지 않았다면 struct node의 주소size 2개를 따로 더했어야 할 것이다)

6. The resulting address is the same as the address of num.c. At that address, we find the integer value of 6.

   (결과값의 주소는 결국 num.c의 주소와 같다. 따라서 결과값은 6이 되는 것이다.)

 

참고로, 구조체의 경우 메모리상 주소지는 연속할당 된다는 특성 때문에 주소이동이 가능한 것이다.

 

문제출처: https://www.sololearn.com/
설명출처: https://stackoverflow.com/questions/63543259/how-the-struct-and-pointer-acts/63543401#63543401

[문제]

9개의 서로 다른 자연수가 주어질 때, 이들 중 최댓값을 찾고 그 최댓값이 몇 번째 수인지를 구하는 프로그램을 작성하시오.

예를 들어, 서로 다른 9개의 자연수

3, 29, 38, 12, 57, 74, 40, 85, 61

이 주어지면, 이들 중 최댓값은 85이고, 이 값은 8번째 수이다.

[입력]

첫 째 줄부터 아홉 번째 줄까지 한 줄에 하나의 자연수가 주어진다. 주어지는 자연수는 100 보다 작다.

[출력]

값을 출력하고, 둘째 줄에 최댓값이 몇 번째 수인지를 출력한다.

백준에서 제시하는 예제 입출력


처음에는 다음과 같은 코드를 작성했다.

이렇게 하면 원하는 결과값이 나오지 않는다.

위의 코드의 문제점은 line13에 i+1을 출력한 것이다.

이렇게 되면 i는 max값이 몇 번째인지를 출력하기보다는 for문을 통해 (총 반복한 횟수)+1이 출력되므로 항상 10(9번+1)이 출력된다.

 

따라서 올바르게 if문의 i를 카운트하기 위해서 다음과 같이 코드를 작성해야 한다.

cnt로 몇 번째인지 저장한다.

 

간단한 구현 문제이다. 정확히 어떤 반복문 안의 변수를 출력해줄 것인지 아는 것이 중요하다.

다음의 코드의 결과를 알아맞춰야 하는 문제이다.

답: SoloLearn SoloLearn (배경을 다르게 해보아라.. 보일 것이다)

 

 

틀린 이유는 내가 제대로 함수포인터를 아직 이해하지 못했기 때문이다.

흔히 생각하는 () 연산자를 통해 함수를 호출하는 것을 생각하여 위의 코드에서 

void(*bar)() = foo;

에서

foo() 가 되어야 하는 줄 알았다.

 

이 참에 공부를 좀 해보자.

 

함수포인터(function pointer)란 함수의 주소를 저장하는 변수다.

https://dojang.io/mod/page/view.php?id=592 (코딩도장)에서 아주 깔끔하게 정리되어 있다 

 

따라서, bar에 foo함수를 할당한다. 다음과 같이 말이다.

 

(*bar)(); 이나 bar();이나 같은 표현이기 때문에 foo()는 2번 수행이 된다.

 

문제출처: https://www.sololearn.com/ 中

http://sololearn.com

 

SoloLearn: Learn to Code

Join Now to learn the basics or advance your existing skills

www.sololearn.com

이 사이트를 통해서 틈틈히 공부하면서 퀴즈를 푸는 재미도 있다.

 

퀴즈의 경우 이 어플을 사용하는 모든 사용자들을 상대로 할 수 있다.

 

퀴즈 뿐 아니라, 언어에 대해서 간단히 공부를 할 수 있기에 추천하는 어플이다.

 

앞으로는 퀴즈를 풀면서 틀리는 부분도 조금씩 정리해서 기록을 남길 생각이다.

[문제]

정수 N개로 이루어진 수열 A와 정수 X가 주어진다. 이때, A에서 X보다 작은 수를 모두 출력하는 프로그램을 작성하시오.


[입력]

첫째 줄에 N과 X가 주어진다. (1 ≤ N, X ≤ 10,000)

둘째 줄에 수열 A를 이루는 정수 N개가 주어진다. 주어지는 정수는 모두 1보다 크거나 같고, 10,000보다 작거나 같은 정수이다.


[출력] 

X보다 작은 수를 입력받은 순서대로 공백으로 구분해 출력한다. X보다 작은 수는 적어도 하나 존재한다.

 

백준에서 제시하는 입출력 예제

 


코딩 작성은 쉬운데 문제를 이해하는 부분에서 살짝 햇갈렸다.. (국어의 문제..)

둘째 줄에서 정수 n개 주어진다는 것은 곧 첫째줄의 첫번째 숫자 갯수 만큼 정수가 주어진다는 뜻이다.

그리고 주어진다는 것은 컴퓨터 내부에서 랜덤으로 주어진다는 것이 아니라, 따로 입력을 한다는 것이다.

괜히 문제를 어렵게 생각할 필요 없다.

있는 그대로 코드를 작성해주면 된다!!

 

 

출처: https://www.acmicpc.net/problem/10871

[문제]

월드 전자는 노트북을 제조하고 판매하는 회사이다. 노트북 판매 대수에 상관없이 매년 임대료, 재산세, 보험료, 급여 등 A만원의 고정 비용이 들며, 한 대의 노트북을 생산하는 데에는 재료비와 인건비 등 총 B만원의 가변 비용이 든다고 한다.

예를 들어 A=1,000, B=70이라고 하자. 이 경우 노트북을 한 대 생산하는 데는 총 1070만 원이 들며, 열 대 생산하는 데는 총 1,700만 원이 든다.

노트북 가격이 C만원으로 책정되었다고 한다. 일반적으로 생산 대수를 늘려 가다 보면 어느 순간 총수입(판매비용)이 총비용(=고정비용+가변비용) 보다 많아지게 된다. 최초로 총수입이 총비용보다 많아져 이익이 발생하는 지점을 손익분기점(BREAK-EVEN POINT)이라고 한다.

A, B, C가 주어졌을 때, 손익분기점을 구하는 프로그램을 작성하시오.


[입력]

첫째 줄에 A, B, C가 빈 칸을 사이에 두고 순서대로 주어진다. A, B, C는 21억 이하의 자연수이다.


[출력] 

첫 번째 줄에 손익분기점 즉 최초로 이익이 발생하는 판매량을 출력한다. 손익분기점이 존재하지 않으면 -1을 출력한다.

 

입력예제 출력예제
1000 70 170 11
1000 150 170 501
1000 70 50 -1
1000000000 1000 1001 1000000001

 

 


1. input().split()으로 문자열을 여러 개 받아서 리스트를 형성할 수 있다. 

2. map()을 통해서 int형태로 바꿔줄 수 있다.

즉,

a, b, c = map(int,input().split())

은 a, b, c에 정수를 받아주는데, 무엇을 받느냐면, input의 값들을 차례 데로 받아주세요~라는 뜻이 된다. 

 

따라서, 다음과 같은 코드로 작성할 수 있다.

a, b, c = map(int,input().split())

if b>=c:
    print(-1)
else:
    print(int(a/(c-b))+1)

a/(c-b))+1가 나오게 되는 이유에 관해서는 C언어로 만든 코드를 작성한 곳에서 조금 더 자세히 알 수 있다.


https://gettingtoknowit.tistory.com/11?category=918026

 

[백준 1712번] 손익분기점

[문제] 월드 전자는 노트북을 제조하고 판매하는 회사이다. 노트북 판매 대수에 상관없이 매년 임대료, 재산세, 보험료, 급여 등 A만원의 고정 비용이 들며, 한 대의 노트북을 생산하는 데에는 재

gettingtoknowit.tistory.com

 

출처: https://www.acmicpc.net/problem/1712

[문제]

월드 전자는 노트북을 제조하고 판매하는 회사이다. 노트북 판매 대수에 상관없이 매년 임대료, 재산세, 보험료, 급여 등 A만원의 고정 비용이 들며, 한 대의 노트북을 생산하는 데에는 재료비와 인건비 등 총 B만원의 가변 비용이 든다고 한다.

예를 들어 A=1,000, B=70이라고 하자. 이 경우 노트북을 한 대 생산하는 데는 총 1070만 원이 들며, 열 대 생산하는 데는 총 1,700만 원이 든다.

노트북 가격이 C만원으로 책정되었다고 한다. 일반적으로 생산 대수를 늘려 가다 보면 어느 순간 총 수입(판매비용)이 총비용(=고정비용+가변비용) 보다 많아지게 된다. 최초로 총수입이 총비용보다 많아져 이익이 발생하는 지점을 손익분기점(BREAK-EVEN POINT)이라고 한다.

A, B, C가 주어졌을 때, 손익분기점을 구하는 프로그램을 작성하시오.


[입력]

첫째 줄에 A, B, C가 빈 칸을 사이에 두고 순서대로 주어진다. A, B, C는 21억 이하의 자연수이다.


[출력] 

첫 번째 줄에 손익분기점 즉 최초로 이익이 발생하는 판매량을 출력한다. 손익분기점이 존재하지 않으면 -1을 출력한다.

 

입력 예제 출력 예제
1000 70 170 11
1000 80 590 2
1000 150 170 501
1000 70 50 -1
1000000000 1000 1001 1000000001

 


상당히 고생했던 문제이다.

일단 문제를 제대로 이해를 하는데까지는 했다.

또한, 문제를 토대로 다음과 같은 식을 만드는 것까지 가능했다

A + B * i < C * i   // 손익분기점

 

문제는 여기서 나는 코드를 다음과 같이 만들었다.

이게 바로 문제의 코드다...

이 코드의 문제를 Stackoverflow에 질문을 한 결과, 다양한 답변 중에 가장 눈에 띈 답변은 다음과 같다.

One thing that is wrong with your code is complexity. You are doing a loop, as if you have skipped a division lesson in the elementary school. Now if the fixed cost is 1000000000, the variable cost is 1, and the price is 2, how much longer does you program runs compared to that of your friend? Another thing that is wrong with your code is that it contains multiplication, again because you have skipped a division lesson in the elementary school. Multiplying large numbers is dangerous. Try A=1000000000, B=1000 and C=1001. What does your program output? Does it look right?

사실 조금 비꼬는 어투가 있지만, 핵심은 나누기를 하지 않고 곱하기를 해서 문제가 생긴다는 것이다 (아마 이 문제는 오버플로우 일 것이라고 생각된다.)

마지막 문장에 주는 예제는...

"A=1000000000, B=1000 and C=1001" 이다.

이렇게 입력된 올바른 프로그램의 경우, 1000000001 이 올바른 답이다.

하지만, 위의 식은 이상한 답이 나온다.

 

따라서, 이 부분을 해결하여 코드를 올바르게 작성할 경우 다음과 같은 코드가 작성된다.

올바른 코드는 이렇게 해야 한다.

 

출처: https://www.acmicpc.net/problem/1712

 

[문제]

Every school morning Mirko is woken up by the sound of his alarm clock. Since he is a bit forgetful, quite often he leaves the alarm on on Saturday morning too. That's not too bad though, since he feels good when he realizes he doesn't have to get up from his warm and cozy bed.

He likes that so much, that he would like to experience that on other days of the week too! His friend Slavko offered this simple solution: set his alarm clock 45 minutes early, and he can enjoy the comfort of his bed, fully awake, for 45 minutes each day.

Mirko decided to heed his advice, however his alarm clock uses 24-hour notation and he has issues with adjusting the time. Help Mirko and write a program that will take one time stamp, in 24-hour notation, and print out a new time stamp, 45 minutes earlier, also in 24-hour notation.

Note: if you are unfamiliar with 24-hour time notation yourself, you might be interested to know it starts with 0:00 (midnight) and ends with 23:59 (one minute before midnight).


상근이는 매일 아침 알람을 듣고 일어난다. 알람을 듣고 바로 일어나면 다행이겠지만, 항상 조금만 더 자려는 마음 때문에 매일 학교를 지각하고 있다.

상근이는 모든 방법을 동원해보았지만, 조금만 더 자려는 마음은 그 어떤 것도 없앨 수가 없었다.

이런 상근이를 불쌍하게 보던, 창영이는 자신이 사용하는 방법을 추천해 주었다.

바로 "45분 일찍 알람 설정하기"이다.

이 방법은 단순하다. 원래 설정되어 있는 알람을 45분 앞서는 시간으로 바꾸는 것이다. 어차피 알람 소리를 들으면, 알람을 끄고 조금 더 잘 것이기 때문이다. 이 방법을 사용하면, 매일 아침 더 잤다는 기분을 느낄 수 있고, 학교도 지각하지 않게 된다.

현재 상근이가 설정한 알람 시각이 주어졌을 때, 창영이의 방법을 사용한다면, 이를 언제로 고쳐야 하는지 구하는 프로그램을 작성하시오.


[입력]

The first and only line of input will contain exactly two integers H and M (0 ≤ H ≤ 23, 0 ≤ M ≤ 59) separated by a single space, the input time in 24-hour notation. H denotes hours and M minutes.


첫째 줄에 두 정수 H와 M이 주어진다. (0 ≤ H ≤ 23, 0 ≤ M ≤ 59) 그리고 이것은 현재 상근이가 설정한 놓은 알람 시간 H시 M분을 의미한다.

입력 시간은 24시간 표현을 사용한다. 24시간 표현에서 하루의 시작은 0:0(자정)이고, 끝은 23:59(다음날 자정 1분 전)이다. 시간을 나타낼 때, 불필요한 0은 사용하지 않는다.


[출력] 

The first and only line of output should contain exactly two integers, the time 45 minutes before input time.


첫째 줄에 상근이가 창영이의 방법을 사용할 때, 설정해야 하는 알람 시간을 출력한다. (입력과 같은 형태로 출력하면 된다.)

입력 예제 출력 예제
10 10 9 25
0 30 23 45
23 40 22 55

 


 

시계를 연상하면서 숫자를 생각하면 된다. m = m+60 부분을 생각하는 것이 관건이다.

 

출처: https://www.acmicpc.net/problem/2884

[문제]

시험 점수를 입력받아 90 ~ 100점은 A, 80 ~ 89점은 B, 70 ~ 79점은 C, 60 ~ 69점은 D, 나머지 점수는 F를 출력하는 프로그램을 작성하시오.


[입력]

첫째 줄에 시험 점수가 주어진다. 시험 점수는 0보다 크거나 같고, 100보다 작거나 같은 정수이다.


[출력] 

시험 성적을 출력한다.

 

입력 예제 출력 예제
100 A
90 A
80 B
70 C
60 D
50 F

 


 

출처: https://www.acmicpc.net/problem/9498

[문제]

N개의 숫자가 공백 없이 쓰여있다. 이 숫자를 모두 합해서 출력하는 프로그램을 작성하시오.


[입력]

첫째 줄에 숫자의 개수 N (1 ≤ N ≤ 100)이 주어진다. 둘째 줄에 숫자 N개가 공백없이 주어진다.


[출력] 

입력으로 주어진 숫자 N개의 합을 출력한다.

 

백준에서 제시하는 입출력 예제들이다.

 


ASCII CODE에 대해서 잘 알아야 풀 수 있는 문제이다.

http://www.asciitable.com/

ASCII CODE로 숫자 n에서 숫자 0을 뺄 경우, n의 값의 정수값을 구할 수가 있다.

예를 들어, 예제에 나오듯

n=1 == 0x31 == 49 이므로,

n=0 == 0x30 == 48 을 뺀다면,

정수값 = 1 이 되는 것이다.

 

이에 따라 line 13의 " - '0' "이 나오는 것이다.

 

 

출처: https://www.acmicpc.net/problem/11720

+ Recent posts