C2007. 5. 30. 22:37
 

/*
 * -------------------------------------
 *     몬테카를로법에 의한 π 계산    *
 * -------------------------------------
 */

 

#include <stdio.h>
#include <stdlib.h>

#define NUM 1000

 

double rnd(void);

int main(void)
{
    double x, y, pai;
    int i,in=0;

    for (i=1; i<=NUM; i++){
        x=rnd();
        y=rnd();
        if (x*x+y*y<=1)
            in++;
    }
    pai=(double)4*in/NUM;
    printf("π값 = %f\n", pai);

    return 0;
}

double rnd(void)        /* 0 ~ 1 사이의 난수 */
{
    return (double)rand()/RAND_MAX;     // 0 ~ 1사이의 난수를 발생 시킨다.
}

 

//  몬테카를로법을 이용해서 PI값을 구한다. 0~1사이의 실수형 난수를 두 개 발생시킨후

이를 x, y라고 하자. 이러한 난수쌍을 어는 정도 발생시키면 1*1크기의 정사각형에 (x, y)로 표시

되는 점이 균일하게 흩뿌려진다. 따라서 정사각형의 면적과 1/4원 면적비는 흩뿌려진 난수의 개수

에 비례한다고 할 수 있다.

 

//  num을 1000으로 설정 해주었기 때문에 그다지 정확하지 않다. 값의 정확도는 난수 발생 횟수의

증가와  rnd()에 의해 발생하는 난수가 얼마나 균일하게 퍼지는지에 따라 크게 달라진다.

Posted by 타망

댓글을 달아 주세요

C2007. 5. 30. 22:36
 

//*  몬테카를로법에 의한 면적 계산  *//

 

#include <stdio.h>
#include <stdlib.h>

#define NUM 1000

 

double rnd(void);

int main(void)
{
    double x, y, s;
   

    int i, in = 0;

   

   for (i=0; i<=NUM; i++){
        x = 2*rnd();
        y = rnd();
        if (x*x/4+y*y<=1)
            in++;
    }
    s = 4.0*(2.0*in/NUM);

    printf("타원의 면적 = %f\n", s);

   

    return 0;
}

 

double rnd(void)       /* 0 ~ 1 사이의 난수 발생 */
{
    return (double)rand()/RAND_MAX;
}

 

// x에 0~2사이의 난수, y에 0~1사이의 난수를 대입해서 2*1의 직사각형 내부에 균일하게

퍼뜨린다. PI값 계산 알고리즘을 정확하게 이해한다면, 면적 계산은 쉽게 해결 된다.

Posted by 타망

댓글을 달아 주세요

C2007. 5. 30. 22:36
 

// 1번 예제

#include <stdio.h>
#include <math.h>             // sin, cos 함수를 사용하기 위해서...

 

void main()
{
  int degree = 0;
  double radian = 0.0;

  printf("원하시는 각(degree)을 입력하세요 :  ");
  scanf("%d", degree);

    // sin, cos 함수들은 일반각을 이용하지 않고 라디안형식의 각을 S
    // 사용하기 때문에 라디안 값으로 변환해야 한다
.
  radian = degree*3.141592/180;

  printf("n");
  printf("cos %d = %fn", degree, cos(radian));
  printf("sin %d = %fn", degree, sin(radian));
}


 

// 2번 예제

#include  <stdio.h>                  
#include  <math.h>                  
#define PI 3.141592654       // <-- 파이값을 정의 합니다

 

void main()
{
     double vSin , vCos , vTan;             // <-- sin , cos , tan 저장할 변수입니다
                                                       // 각 함수들 반환값이 double형이라
                                                      // double형으로 선언합니다
     int Degree;                                 // <-- 각도를 저장할 변수입니다

     printf("각도를 입력하세요 : ");
     scanf("%d" , &Degree);                  // 각도를 입력받습니다

     vSin = sin(Degree * (PI / 180));     // 각도를 라디언으로 바꿔서 sin 함수안에 넣습니다
     vCos = cos(Degree * (PI / 180));
     vTan = tan(Degree * (PI / 180));

     printf("sin = %f \ncos = %f \ntan = %f\n" , vSin , vCos , vTan);
}

Posted by 타망

댓글을 달아 주세요

C2007. 5. 30. 22:35
 

/*
 * -------------------------
 *     유클리드 호제법     *
 * -------------------------
 */

 

#include <stdio.h>

int main(void)
{
    int a,b,m,n;

    printf("두 정수를 입력하세요. : ");
    scanf("%d %d", &a, &b);

    m=a; n=b;
   

    while (m!=n){
        if (m>n)
            m=m-n;
        else
            n=n-m;
    }
    printf("최대공약수 = %d\n", m);

    return 0;
}

 

 

// 실행결과

    두 정수를 입력하시오 : 128 72

    최대공약수 = 8

 

// 기계적인  반복으로 최대공약수를 구하는 방법인 컴퓨터 지향 알고리즘으로는

유클리드(Euclid)호제법이 있다. 알고리즘을 간단히 정리하면 다음과 같다.

    

     1. m과 n이 같지 않으면 다음을 반복한다.

    2. m>n이면 m-n, 그렇지 않으면 n=n-m이다.

    3. m(또는 n)이 구하고자 하는 최대공약수 다.

Posted by 타망

댓글을 달아 주세요

C2007. 5. 30. 22:35
 

/*
 * ---------------------------
 *      파스칼의 삼각형      *
 * ---------------------------
 */

 

#include <stdio.h>
#define N 12

long combi(int,int);

int main(void)
{
    int n,r,t;

    for (n=0;n<=N;n++){
        for (t=0;t<(N-n)*3;t++)        /* 공백 */
            printf(" ");
        for (r=0;r<=n;r++)
            printf("%3ld   ",combi(n,r));
        printf("\n");
    }

 return 0;
}

long combi(int n,int r)
{
    int i;
    long p=1;

    for (i=1;i<=r;i++)
        p=p*(n-i+1)/i;
    return p;
}

 

// nCr을 구하는 프로그램을 이용해서 파스칼의 삼각형을 위와 같이 나타낼 수 있다.

Posted by 타망

댓글을 달아 주세요

C2007. 5. 30. 22:34
 

/*
 * --------------------
 *     순위 매김     *
 * --------------------
 * 시험점수의 점수별 순위를 구한다.

 */

 

#include <stdio.h>

#define Num 10

int main(void)     /* 순위 매김 */
{
    static int a[]={56,25,67,88,100,61,55,67,76,56};
    int rank[Num];
    int i,j;

    for (i=0;i<Num;i++) {
        rank[i]=1;
        for (j=0;j<Num;j++) {
            if (a[j]>a[i])
                rank[i]++;
        }
    }

    printf("   점수  순위\n");
    for (i=0;i<Num;i++){
        printf("%6d%6d\n",a[i],rank[i]);
    }

    return 0;
}

 

// 위의 순위를 구하는 알고리즘에서는 데이터가 n개인 경우, 반복 횟수가 n2이 된다. 따라서

데이터 수가 증가하면 처리하는 데 시간이 많이 걸린다. 따라서 반복 횟수를 줄이기 위한

순위 매김 알고리즘을 생각해본다. 다음 알고리즘이 그 예제이다.

 

// 개선된 순위 매김

 

#include <stdio.h>

#define Num 10

#define Max 100

#define Min 0

 

int main(void)    

{
    static int a[] = {56,25,67,88,100,61,55,67,76,56};
    int i, rank[Max+2];
   

    for (i=Min; i<Max; i++)
         rank[i]=0;                        //  0으로 초기화
        for (i=0; i<Num; i++)         //  각 점수를 첨자로 하는 배열요소에 +1
           rank[a[i]]++;                          
   

    rank[Max+1] = 1;                 //  바로 오른쪽 요소의 값을 더함

    for(i=Max; i>=Min; i--)

       rank[i] = rank[i]+rank[i+1];


    printf("   점수  순위\n");
    for (i=0; i<Num; i++){
        printf("%6d%6d\n", a[i], rank[a[i]+1]);    // 점수 +1의 위치에 순위가 저장됨
    }

    return 0;
}

Posted by 타망

댓글을 달아 주세요

C2007. 5. 30. 22:34
 

/*
 * ------------------------------------
 *     랜덤한 순열

 * ------------------------------------
 */

 

#include <stdio.h>
#include <stdlib.h>

#define N 20

int irnd(int);

int main(void)
{
    int i,j,d,a[N+1];

    for (i=1;i<=N;i++)
        a[i]=i;

    for (i=N;i>1;i--){
        j=irnd(i-1);
        d=a[i];a[i]=a[j];a[j]=d;
    }

    for (i=1;i<=N;i++)
        printf("%d ",a[i]);

    printf("\n");

    return 0;
}

 

int irnd(int n)        /* 1 ~ N 의 난수 */
{
    return (int)(rand()%n + 1);
}

 

// a[1]~a[N]에 1~N의 수를 순서대로 저장한다.

1~N-1중에서 난수 j를 얻는다. 이것을 첨자로 하는 배열 a[j]와 a[N]을 교환한다. 이렇게 해서

a[N]항의 순열은 확정된다.

Posted by 타망

댓글을 달아 주세요

C2007. 5. 30. 22:33

/*
 * ---------------------------------------
 *     2 ~ N 사이의 모든 소수를 추출     *
 * ---------------------------------------
 */


#include <stdio.h>
#include <math.h>

#define NUM 1000

int main(void)
{
    static int prime[NUM/2+1];
    int i,n,m=0,Limit;

    for (n=2;n<=NUM;n++){
        Limit=(int)sqrt(n);
        for (i=Limit;i>1;i--){
            if (n%i == 0)
                break;
        }
        if (i==1)
            prime[m++]=n;
    }

    printf("2 ~ %d 사이의 소수\n", NUM);
    for (i=0;i<m;i++)
        printf("%5d",prime[i]);

    printf("\n");
   
    return 0;
}


// 2~N 까지의 모든 정수 중에서 소수를 모두 구한다.

Posted by 타망

댓글을 달아 주세요

C2007. 5. 30. 22:33

/*
 * --------------------
 *      소인수분해    *
 * --------------------
 */


#include <stdio.h>

int main(void)
{
    int a,n;

    while (printf("Number ? "),scanf("%d",&n)!=EOF) {
        a=2;
        while (n>=a*a){
            if (n % a ==0){
                printf("%d*",a);n=n/a;
            }
            else
                a++;
        }
        printf("%d\n",n);
    }
   
    return 0;
}


// 양의 정수를 소수의 곱으로 분해하는 것을 소인수 분해라고 한다.

Posted by 타망

댓글을 달아 주세요

C2007. 5. 30. 22:32

/*
 * ----------------------
 *      소수의 판정     *
 * ----------------------
 */


#include <stdio.h>
#include <math.h>

int main(void)
{
    int i,n,Limit;

    while (printf("data? "),scanf("%d",&n)!=EOF) {
        if (n>=2){
            Limit=(int)sqrt(n);
            for (i=Limit;i>1;i--) {
                if (n%i == 0)
                    break;
            }
            if (i==1)
                printf("소수\n");
            else
                printf("소수가 아님\n");
        }
    }
   
    return 0;
}

 

// 소수란 다음과 같이 1과 자기 자신외에는 약수를 갖지 않는 수를 말한다.

    2, 3, 5, 7 , 11 (단, 1은 소수가 아니다.)

// n이 소수인지 아닌지는 n이 n외의 정수로 나누어 떨어지는지 아닌지를 통해서 알 수 있다.

n이하의 정수에서 2까지의 수로 나누어서 떨어지는 수가 있으면 소수가 아니므로 루프를

빠져나오면 된다.

Posted by 타망

댓글을 달아 주세요