一、整数的一些性质及解法
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;
}
}