整数的一些基本性质 + 初探博弈论

本文介绍整数运算的基本概念,包括最大公约数、最小公倍数的计算方法及素数判断,同时探讨最大不可组合数的问题。此外,文章还讲解了组合博弈论的应用,通过转换为二进制问题解决整数难题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、整数的一些性质及解法

1.求两个整数的最大公约数

public static void main(String[] args){
    int a = 15;
    int b = 40;
    for(int i = a; i >= 1; i--){
        if(a % i == 0 && b % i ==0){
            System.out.println(i);
            break;
        }
    }
}

采用辗转相除法解答

/**
 * 求最大公约数
 * 辗转相除法   [a , b] -----> [b % a, a]
 */
public static void main(String[] args){
    System.out.println(gcd(40,15));
}
private static int gcd(int a, int b){
    if(a == 0){
        return b;
    }
    return gcd(b % a, a);
}

2.求两个整数的最小公倍数

/**
 * 求最小公倍数
 * a * b / gcd(a,b)
 */
public static void main(String[] args){
    System.out.println(40 * 15 /gcd(40,15));
}
private static int gcd(int a, int b){
    if(a == 0){
        return b;
    }
    return gcd(b % a, a);
}

3.素数问题
这里写图片描述
求解思路:
采用筛法:
这里写图片描述
即从第一个素数2开始,依次将2的倍数筛除,然后依次选择下一个素数,并筛除该素数的倍数。

代码如下:

public static void main(String[] args){
    int N = 1000 * 1000 * 10;
    int m = 100001;
    byte[] a = new byte[N];
    for(int i = 2; i < N/2; i++){
        if(a[i] == 1){
            continue;
        }
        for(int j = 2; j < N/i; j++){
            if(j * i < N){
                a[j * i] = 1;
            }
        }
    }
    int n = 0;
    for(int i = 2; i < N; i++){
        if(a[i] == 0){
            n++;
            if(n == m){
                System.out.print(i + " ");
            }
        }
    }
    System.out.println("m = "+m);
}

4.求最大不能组合的数字
题目如下:
这里写图片描述
求解思路:
设组合的两个数字为a,b(a < b),从0开始依次查找二者可以组合出的数字,当可以组合出的数字连续出现a次时(第a次连续出现的位置为n),最大不能组合出的数字则为n-a

代码如下:

public class Main {
    static final int N = 1000 * 100;
    public static void main(String[] args){
        f(3,5);
    }
    private static void f(int a, int b){
        int[] arr = new int[N];
        for(int i = 0; i < N / a; i++){
            for(int j = 0; j < (N - a * i) / b; j++){
                if((a * i + b * j) < N){
                    arr[a * i + b* j] =1;
                }
            }
        }
        int n = 0;
        for(int i = 0; i < arr.length; i++){
            if(arr[i] == 1){
                n++;
                if(n >= a){
                    System.out.println(i - a);
                    break;
                }
            }else{
                n =0;
            }
        }
    }
}

二、组合博弈论
例题如下:
这里写图片描述
这里写图片描述

求解思路:
此类问题都可采用Nimm游戏的思路,即将整数问题化为2进制问题,依次将每一个整数化为2进制,一数一行整齐排列,对比每一列数字之和是否为偶数。将和不为偶数的数字列改动某一项,使其变为偶数,则改动前后的数字即为答案(将2进制再化为10进制整数)

这里写图片描述

代码如下:

import java.util.Scanner;

/** 
 * @author 作者 : Cactus
 * @version 创建时间:2018-2-24 上午10:56:40 
 */
public class Main {
/**
 * 组合博弈论
 * @param args
 */
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String[] ss = sc.nextLine().split(" ");
        int[] x = new int[ss.length];
        for(int i = 0; i < x.length; i++){
            x[i] = Integer.parseInt(ss[i]);
        }
        test(x);
    }
    private static void test(int[] x){
        for(int i = 0; i < x.length - 1; i++){
            for(int k = x[i] + 1; k < x[i + 1]; k++){
                int old = x[i];
                x[i] = k;
                try{
                    if(f(x)){
                        System.out.println(old + " " + k);
                    }
                }finally{
                    x[i] = old;
                }
            }
        }
    }
    private static boolean f(int[] x){
        String[] y = new String[x.length / 2];
        int m = 0;
        for(int i = 0; i < x.length / 2; i++){
            y[i] =  Integer.toBinaryString(x[i * 2 + 1] - x[i * 2] - 1);
            if(y[i].length() > m){
                m = y[i].length();
            }
        }
        for(int i = 0; i < m; i++){
            boolean tag = true;
            for(int j = 0; j < y.length; j++){
                int k = y[j].length() - (m - i);
                if(k >= 0 && y[j].charAt(k) == '1'){
                    tag = !tag;
                }
            }
            if(tag == false){
                return false;
            }
        }
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喜鹊先生Richard

随缘~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值