《Java程序设计 一种跨学科的方法》第1章第3节练习

1.3.32 Ramanujan的出租车

Srinivasa Ramanujan是著名的印第安数学家,他以对数字的直觉而闻名。一天当英国数学家G.H.Hardy来拜访他,Hardy谈论他乘坐的出租车号是1729,一个相当无趣的数字。而Ramanujan回答,”不,Hardy!不,Hardy!“,这是一个非常有趣的数字。在两种不同方式中,这是可以表示成两个数的立方和的最小数字。验证这个断言。通过编写程序,使用命令行参数N,并显示所有小于或等于N的整数,这些整数可以使用两种不同的方式来表达两个数立方和。换句话说,找到不同正整数a b c d,如a^3+b^3=c^3+d^3。

public class Main {

    public static void main(String[] args) {
        int n = Integer.parseInt(args[0]);
        for (int a = 1; a < n; a++) {
            for (int b = 1; b < n; b++) {
                for (int c = 1; c < n; c++) {
                    for (int d = 1; d < n; d++) {
                        if (a == b || a == c || a == d || b == c || b == d || c == d)
                            continue;
                        int sum = a * a * a + b * b * b;
                        if (sum == c * c * c + d * d * d) {
                            System.out.printf("%d = %d^3+%d^3 = %d^3+%d^3\n", sum, a, b, c, d);
                        }
                    }
                }
            }
        }
    }
}
1.3.33 检验和

国际标准书号(ISBN)是独特地指定书的10位数代码。最右的位是校验和位,它可以根据其他9位数确定,条件是d1+2d2+3d3+..+10d10必须是11的倍数。校验和位di可以是从0到10的任何一个值。国际标准书号的惯例是使用字符X表示10。编写一个程序,使用来自命令行的9位整数,计算校验和并打印国际标准书号的数字。

public class Main {

    public static void main(String[] args) {
        String s = args[0];
        if (s != null && s.length() != 9) {
            System.out.println("error");
            return;
        }
        int sum = 0;
        for (int i = 0; i < 9; i++) {
            int n = s.charAt(i) - '0';
            sum += (i + 1) * n;
        }
        for (int i = 0; i <= 10; i++) {
            if ((sum + 10 * i) % 11 == 0) {
                if (i < 10)
                    System.out.println(s + i);
                else
                    System.out.println(s + "X");
            }
        }
    }
}
1.3.34 计算素数

编写程序,使用来自命令行参数N,找到小于或等于N的素数。运行这个程序来打印小于或等于1亿的素数。

public class Main {

    public static void main(String[] args) {
        int n = Integer.parseInt(args[0]);
        if (n > 2)
            System.out.print(2 + " ");
        for (int i = 3; i < n; i += 2) {
            boolean isprime = true;
            for (int j = 2; j < i; j++) {
                if (i % j == 0) {
                    isprime = false;
                    break;
                }
            }
            if (isprime)
                System.out.print(i + " ");
        }
    }
}
1.3.35 二维随机行走

二维随机行走模拟微粒在点栅格移动的行为。在每一步,随机行走可以直到北部、南部、东部或西部,概率均为1/4,独立前面的移动。编写一个程序,使用命令行参数并估计从2N*2N的正方形中心出发,到正方形边界,行走需要多长时间。

public class Main {

    public static void main(String[] args) {
        int n = Integer.parseInt(args[0]);
        int count = 0;
        int x = 0, y = 0;
        while (x != n && x != -n && y != n && y != -n) {
            double rand = Math.random();
            if (rand < 0.25)
                ++x;
            else if (rand < 0.50)
                --x;
            else if (rand < 0.75)
                ++y;
            else
                --y;
            ++count;
        }
        System.out.println(count);
    }
}
1.3.36 指数函数

假设x是double类型的正变量。编写程序,使用泰勒级数扩展来计算e^x。

public class Main {

    public static void main(String[] args) {
        double x = Double.parseDouble(args[0]);
        double term = 1.0;
        double sum = 0.0;
        for (int i = 1; sum != sum + term ; i++) {
            sum += term;
            term *= x / i;
        }
        System.out.println(sum);
        System.out.println(Math.exp(x));
    }
}

1.3.37 三角函数

使用泰勒级数计算sin x。

public class Main {

    public static void main(String[] args) {
        double x = Double.parseDouble(args[0]);
        double term = x;
        double sum = 0.0;
        double sign = 1;
        for (int i = 1; sum != sum + term ; i += 2) {
            sum +=  term * sign;
            term *= x * x / ((i + 1) * (i + 2));
            sign = -sign;
        }
        System.out.println(sum);
        System.out.println(Math.sin(x));
    }
}

1.3.39 Pepys问题

在1693 Samuel Pepys问Isaac Newton,哪个更有可能:投6次骰子,至少1次可得到1,或投12次骰子,至少得到2次1。编写一个程序,能让牛顿快速地回答这个问题。

public class Main {

    public static void main(String[] args) {
        int count1 = 0, count2 = 0;
        for (int i = 0; i < 1000000; i++) {
            for (int j = 0; j < 6; j++) {
                long n = Math.round(Math.random() * 100) % 10;
                if (n == 0)
                    ++count1;
            }
            for (int j = 0; j < 12; j++) {
                long n = Math.round(Math.random() * 100) % 10;
                if (n == 0)
                    ++count2;
            }
        }
        System.out.printf("%d %d\n", count1, count2);
    }
}
1.3.40 游戏模拟

在20世纪70年代电视知识竞赛”让我们做个交易“,给竞争者提供3个门。在其中的一扇门后有可观的奖金。在竞争者选择一扇门之后,主持人打开另外两个门之一(当然从未出现过奖金)。然后给竞争都提供机会来换成另一个未打开的门。竞争者应该如何做呢?直觉可能认为竞争者最初挑选的门和另一扇未打开的门都同样可能包含奖金,因此不需要换一扇门。编写一个程序MonteHall来测试这种直觉的模拟。程序应该使用命令行参数N,并使用两个策略之一(换门或不换门)来玩N次这个游戏,并打印每一种策略的成功机会。

public class Main {

    public static void main(String[] args) {
        int n = Integer.parseInt(args[0]);
        int count1 = 0, count2 = 0;
        for (int i = 0; i < n; i++) {
            int door = (int) (Math.random() * 100) % 3;
            int choice = (int) (Math.random() * 100) % 3;
            int rest = 0;
            if (door == choice) {
                switch (door) {
                    case 0:
                        rest = 1;
                        break;
                    case 1:
                        rest = 2;
                        break;
                    case 2:
                        rest = 0;
                        break;
                }
            } else {
                rest = door;
            }
            if (choice == door) ++count1;
            if (rest == door) ++count2;
        }
        System.out.println("不换门:" + count1);
        System.out.println("换门:" + count2);
    }
}
1.3.41 五个数的中值。

编写一个程序,使用5个来自命令行的不同整数,并打印中值(这个值比其中的两个小但比其余的两个大)。

import java.util.Arrays;

public class Main {

    public static void main(String[] args) {
        int[] num = new int[args.length];
        for (int i = 0; i < num.length; i++) {
            num[i] = Integer.parseInt(args[i]);
        }
        Arrays.sort(num);
        System.out.println(num[num.length / 2]);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值