C言語プログラミング:反復構造と数学的アルゴリズムの実装例

指定された精度での交互級数の和

特定の精度(eps)に達するまで、数列 1 - 1/4 + 1/7 - 1/10 + ... の部分和を計算します。各項の絶対値が指定された精度以下になった時点で計算を終了します。

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

int main() {
    double precision, term, total = 0.0;
    int denominator = 1, sign = 1;

    if (scanf("%lf", &precision) != 1) return 1;

    do {
        term = (double)sign / denominator;
        total += term;
        denominator += 3;
        sign = -sign;
    } while (fabs(term) > precision);

    printf("sum = %.6f\n", total);
    return 0;
}

数当てゲームのロジック実装

システムが生成した乱数(または固定値)を当てるゲームです。試行回数に応じて評価メッセージ(Bingo!, Lucky You!, Good Guess!)を表示し、回数制限を超えた場合はゲームオーバーとなります。

#include <stdio.h>

int main() {
    int answer, max_attempts, guess;
    int count = 0, solved = 0;

    scanf("%d %d", &answer, &max_attempts);

    for (int i = 0; i < max_attempts; i++) {
        scanf("%d", &guess);
        count++;

        if (guess < 0) break;

        if (guess > answer) {
            printf("Too big\n");
        } else if (guess < answer) {
            printf("Too small\n");
        } else {
            solved = 1;
            break;
        }
    }

    if (!solved) {
        printf("Game Over\n");
    } else if (count == 1) {
        printf("Bingo!\n");
    } else if (count <= 3) {
        printf("Lucky You!\n");
    } else {
        printf("Good Guess!\n");
    }

    return 0;
}

ネイピア数 e の近似値計算

階乗を用いた級数展開により、e の近似値を計算します。

#include <stdio.h>

double calculate_factorial(int n) {
    double res = 1.0;
    for (int i = 1; i <= n; i++) res *= i;
    return res;
}

int main() {
    int n;
    double e_approx = 1.0;
    scanf("%d", &n);

    for (int i = 1; i <= n; i++) {
        e_approx += 1.0 / calculate_factorial(i);
    }

    printf("%.8lf\n", e_approx);
    return 0;
}

数列からの最小値探索

入力された N 個の整数の中から、最小の値を特定します。

#include <stdio.h>

int main() {
    int n, current, min_val;
    if (scanf("%d", &n) != 1 || n <= 0) return 0;

    scanf("%d", &min_val);
    for (int i = 1; i < n; i++) {
        scanf("%d", &current);
        if (current < min_val) {
            min_val = current;
        }
    }

    printf("min = %d\n", min_val);
    return 0;
}

素数の統計と総和

指定された範囲 [M, N] に含まれる素数の個数とその総和を求めます。

#include <stdio.h>
#include <stdbool.h>

bool is_prime(int num) {
    if (num < 2) return false;
    for (int i = 2; i * i <= num; i++) {
        if (num % i == 0) return false;
    }
    return true;
}

int main() {
    int start, end, count = 0, sum = 0;
    scanf("%d %d", &start, &end);

    for (int i = start; i <= end; i++) {
        if (is_prime(i)) {
            count++;
            sum += i;
        }
    }

    printf("%d %d\n", count, sum);
    return 0;
}

正の奇数の総和計算

0 以下の数値が入力されるまで整数を読み込み、その中の正の奇数のみを合計します。

#include <stdio.h>

int main() {
    int val, total_odd = 0;
    while (scanf("%d", &val) == 1 && val > 0) {
        if (val % 2 != 0) {
            total_odd += val;
        }
    }
    printf("%d\n", total_odd);
    return 0;
}

冪級数展開による関数の近似

x の冪乗と階乗を用いた級数の和を、項が一定値未満になるまで計算します。

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

double get_fact(int n) {
    double res = 1.0;
    for (int i = 1; i <= n; i++) res *= i;
    return res;
}

int main() {
    double x, sum = 1.0, term;
    int k = 1;
    scanf("%lf", &x);

    do {
        term = pow(x, k) / get_fact(k);
        sum += term;
        k++;
    } while (fabs(term) >= 0.00001);

    printf("%.4f\n", sum);
    return 0;
}

分数列の和

2/1, 3/2, 5/3, 8/5, ... のような、分子と分母がフィボナッチ数列のように変化する数列の和を求めます。

#include <stdio.h>

int main() {
    int n;
    double a = 2.0, b = 1.0, sum = 0, temp;
    scanf("%d", &n);

    for (int i = 0; i < n; i++) {
        sum += a / b;
        temp = a;
        a = a + b;
        b = temp;
    }

    printf("%.2lf\n", sum);
    return 0;
}

特殊な数値文字列の総和

a + aa + aaa + ... + aa...a (n個) の総和を計算します。

#include <stdio.h>

int main() {
    int a, n;
    long long current_val = 0, total_sum = 0;
    scanf("%d %d", &a, &n);

    for (int i = 1; i <= n; i++) {
        current_val = current_val * 10 + a;
        total_sum += current_val;
    }

    printf("s = %lld\n", total_sum);
    return 0;
}

硬貨の組み合わせ問題

指定された金額を5分、2分、1分の硬貨で支払う際の組み合わせ(各1枚以上)を列挙し、そのパターン数を数えます。

#include <stdio.h>

int main() {
    int money, count = 0;
    scanf("%d", &money);

    for (int f5 = money / 5; f5 >= 1; f5--) {
        for (int f2 = money / 2; f2 >= 1; f2--) {
            int f1 = money - (f5 * 5 + f2 * 2);
            if (f1 >= 1) {
                printf("fen5:%d, fen2:%d, fen1:%d, total:%d\n", f5, f2, f1, f5 + f2 + f1);
                count++;
            }
        }
    }
    printf("count = %d\n", count);
    return 0;
}

水仙花数(アームストロング数)

N桁の正の整数について、各桁の数字のN乗の和が元の数字と等しくなる数を全て出力します。

#include <stdio.h>

int fast_pow(int base, int exp) {
    int res = 1;
    for (int i = 0; i < exp; i++) res *= base;
    return res;
}

int main() {
    int n;
    scanf("%d", &n);
    int start = fast_pow(10, n - 1);
    int end = fast_pow(10, n);

    for (int i = start; i < end; i++) {
        int sum = 0, temp = i;
        while (temp > 0) {
            int digit = temp % 10;
            sum += fast_pow(digit, n);
            temp /= 10;
        }
        if (sum == i) printf("%d\n", i);
    }
    return 0;
}

最大公約数と最小公倍数

ユークリッドの互除法を用いて、2つの整数の最大公約数(GCD)と最小公倍数(LCM)を算出します。

#include <stdio.h>

int main() {
    long long m, n, a, b, temp, gcd, lcm;
    scanf("%lld %lld", &m, &n);
    a = m; b = n;

    while (b != 0) {
        temp = a % b;
        a = b;
        b = temp;
    }
    gcd = a;
    lcm = (m * n) / gcd;

    printf("%lld %lld\n", gcd, lcm);
    return 0;
}

ボールの落下とリバウンド

高さ H からボールを落とし、N回跳ね返った後の総移動距離と、N回目の跳ね返り高さを求めます。

#include <stdio.h>

int main() {
    double height, dist = 0;
    int n;
    scanf("%lf %d", &height, &n);

    if (n == 0) {
        printf("0.0 0.0\n");
        return 0;
    }

    dist = height;
    for (int i = 1; i < n; i++) {
        height /= 2.0;
        dist += height * 2.0;
    }
    height /= 2.0;

    printf("%.1f %.1f\n", dist, height);
    return 0;
}

菱形パターンの出力

アスタリスクを用いて、指定されたサイズの菱形を描画します。

#include <stdio.h>

int main() {
    int n;
    scanf("%d", &n);
    int mid = n / 2 + 1;

    for (int i = 1; i <= mid; i++) {
        for (int j = 1; j <= mid - i; j++) printf("  ");
        for (int j = 1; j <= 2 * i - 1; j++) printf("* ");
        printf("\n");
    }
    for (int i = mid - 1; i >= 1; i--) {
        for (int j = 1; j <= mid - i; j++) printf("  ");
        for (int j = 1; j <= 2 * i - 1; j++) printf("* ");
        printf("\n");
    }
    return 0;
}

ウサギの繁殖問題(フィボナッチ)

つがいのウサギが一定の規則で増えるとき、総数が N に達する月数を求めます。

#include <stdio.h>

int main() {
    int target, month = 1;
    int f1 = 1, f2 = 1, f3 = 1;
    scanf("%d", &target);

    while (f3 < target) {
        f3 = f1 + f2;
        f1 = f2;
        f2 = f3;
        month++;
    }

    if (target == 1) printf("1\n");
    else printf("%d\n", month + 1);

    return 0;
}

タグ: c-language Algorithms math Programming-Logic

6月21日 01:19 投稿