C언어/참고서: C언어 콘서트

C언어 27차시 반복문 연습문제 2, 원의 방정식,

Olivia-BlackCherry 2023. 3. 27. 10:01

목차

    1. 파이 구하기

    <사전 개념 1: 원의 방정식>

    x, y 축으로 표현된 좌표평면 위에서 반지름이 r, 원의 중심이 (0,0)이라면

    원 위의 임의의 점을 P(x,y)라고 하자.

    1) 원의 자취를 x, y의 관계로 나타내보자.  

    2) 임의의 점 x, y가 원 안에 있는 경우 

     

    3) 임의의 점 x, y가 원 밖에 있는 경우

     

    <사전 개념2: 원의 넓이>

    원의 넓이 = 반지름 x 반지름 x pie

     

     

    <사전 지식: 몬테카를로 시뮬레이션>

    몬테카를로 시뮬레이션은 난수를 이용해서 수학적인 문제, 물리학적인 문제를 해결하는 기법이다. 

    아래와 같이 사각형과 원을 그리고 난수를 생성해서 그림 위에 표시한다. 

    원의 반지름은 1, 원의 면적은 pie, 사각형의 면적은 4이다. 

     

    따라서 점이 원 내부에 찍힐 확률(빨강점)은 아래와 같다.

    원의 면적 / 사각형의 면적 =  pie / 4

     

    랜덤함수 rand()로 양의 정수값을 발생시켜, 그 중 가장 큰 값으로 정규화하여

    0~1 사이의 값을 구해준 다음 확률을 구한다. 

     

    마지막에는 pie값을 구해야하므로 x4 를 한다. 

    출처: 블로그 공부하는 박사곰(2021.8.12)

     

    ♣결과

    ♧코드

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <math.h>
    
    int main(void)
    {	
    	double x, y; // 좌표 평면상의 두 점
    	int niter, inside_dots;  // 반복횟수, 원 안에 찍히는 점의 개수
    	double z; 	// z는 원의 자취를 나타내는 원의 방정식
    	double pie;
    
    	srand(time(NULL)); // 난수 생성하기 위한 조취
    	inside_dots = 0;
    	for (niter = 1; niter <= 1000; niter++) {
    		// x, y 두 점을 0~1 값을 갖도록 정규화한다.
    		x = (double)rand() / RAND_MAX;
    		y = (double)rand() / RAND_MAX;
    		z = x * x + y * y;
    
    		// 원 안에 z값이 있다면 원 안에 점이 찍힌다.
    		if (z <= 1) {
    			inside_dots++;
    		}
    
    		// 원 안에 찍힌 점의 개수/전체 점의 개수 X 4
    		pie = (double)inside_dots / niter* 4;
    	}
    	printf("pie의 값은 %lf입니다\n", pie);
    	return 0;
    }//olivia_codingschool

     

     

    2. NIM 게임 구현하기

    NIM 게임은 스틱들의 뭉치에서, 사용자와 컴퓨터가 번갈아 0~3개 사이로 스틱을 가져간다. 

    마지막 스틱을 가져가는 사람이 이긴다.

     

    ♣결과

    ♧코드

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int main(void)
    {
    	int sticks, user, computer;
    	sticks = 12;
    	srand(time(NULL));
    
    	while (1) {
    		printf("몇 개를 가져가시겠습니까(0~3개)? ___\b\b\b");
    		scanf("%d", &user);
    		sticks -= user;
    		printf("남은 스틱 개수는  %d입니다!\n", sticks);
    		if (sticks <= 0) {
    			printf("당신이 이겼습니다!\n");
    			break;
    		}
    
    		computer = rand() % 4;
    		sticks -= computer;
    		printf("컴퓨터가 %d개 가져가서, 남은 스틱 개수는  %d입니다!\n\n", computer, sticks);
    		if (sticks <= 0) {
    			printf("컴퓨터가 이겼습니다!\n");
    			break;
    			}
    		}
    		return 0;
    }
    
    //olivia_codingschool

     

    위의 코드에서 문제점을 발견해보자. 

    문제는, 마지막에 남은 스틱수가 컴퓨터가 가져가고자 하는 수보다 작으면 음수 값을 발생시킨다는 것이다.

    발생한 난수가 현재 스틱 개수보다 클 때의 조건을 하나 더 걸어주면 간단히 해결된다. 

    if (computer > sticks) {
    			computer = sticks;
    		}

    <전체 코드>

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int main(void)
    {
    	int sticks, user, computer;
    	sticks = 12;
    	srand(time(NULL));
    
    	while (1) {
    		printf("몇 개를 가져가시겠습니까(0~3개)? ___\b\b\b");
    		scanf("%d", &user);
    		sticks -= user;
    		printf("남은 스틱 개수는  %d입니다!\n", sticks);
    		if (sticks <= 0) {
    			printf("당신이 이겼습니다!\n");
    			break;
    		}
    
    		computer = rand() % 4;
    		if (computer > sticks) {
    			computer = sticks;
    		}
    		sticks -= computer;
    		printf("컴퓨터가 %d개 가져가서, 남은 스틱 개수는  %d입니다!\n\n", computer, sticks);
    		if (sticks <= 0) {
    			printf("컴퓨터가 이겼습니다!\n");
    			break;
    			}
    		}
    		return 0;
    }

     

     

    3.  코드 실행 결과 a

    ♧코드

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int main(void)
    {
    	short i;
    	for (i = 1; i >= 0; i++)
    		printf("%d\n", i);
    		return 0;
    }
    
    //olivia_codingschool

    ♣결과

     

     

    4. 코드 실행 결과 b

    ♧코드

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int main(void)
    {
    	int i = 0;
    	for (; ; ) // 무한루프
    	{
    		i++;
    		if (i > 7)
    			break; //종료조건
    		if (i < 3)
    			continue; //나머지 문장 건너뛰기
    		printf("%d \n", i);
    	}
    }

    ♣결과