数论总结

  • 大数问题:
    • 使用类库中的  BigInteger与 BigDecimal
    • 例如特训题中的大数问题





  • 有理数表示:
    • 使用String工具类的String.format("%.2f", 7.335334) 输出7.34



  • 进制问题
    • 类库中的Integer的方法
      • 以任意进制输入 parseInt(String s, int radix)
      • 以任意进制输出 Integer.toString(n,2)



     
[4.1 奇怪的捐赠]
地产大亨Q先生临终的遗愿是:拿出100万元给X社区的居民抽奖,以稍慰藉心中愧疚。
麻烦的是,他有个很奇怪的要求:
1. 100万元必须被正好分成若干份(不能剩余)。
每份必须是7的若干次方元。
比如:1元, 7元,49元,343元,...
2. 相同金额的份数不能超过5份。

3. 在满足上述要求的情况下,分成的份数越多越好!

请你帮忙计算一下,最多可以分为多少份?


转七进制
package 数论;

public class 奇怪的捐赠
{

	public static void main(String[] args)
	{
		String string=Integer.toString(1000000,7);
		int sum=0;
		for (int i = 0; i < string.length(); i++)
		{
			sum+=Integer.parseInt(string.charAt(i)+"");
		}
		System.out.println(sum);
	}

}





  • 整数与整除问题

尼姆堆
有3堆硬币,分别是3,4,5
二人轮流取硬币。
每人每次只能从某一堆上取任意数量。
不能弃权。
取到最后一枚硬币的为赢家。

求先取硬币一方有无必胜的招法。



模2的加法,一但达到二,就对二去摸 也就是异或
1+1=0, 1+0=1, 0+1=1, 0+0=0


证明..如果和为0,无论怎么拿,都会!=0
如果非0,总有办法...0
package 数论;

public class 尼姆堆
{
	/*
	 * 		10
	 * 	   101
	 * 	  1100
	 *    1110
	 *   ------ 模2的加法 结果是0 剩给谁谁输
	 *    0101
	 */
	public static void main(String[] args)
	{
		int []a={2,5,12,14};// 10 101 1100 1110
		f(a);
	}

	private static void f(int[] a)
	{
		int sum=0;
		for (int i = 0; i < a.length; i++)
		{
			sum^=a[i];
		}
		if (sum==0)
		{
			System.out.println("必输");
			return ;//必输
		}
		
//		System.out.println(sum^a[a.length-1]);
		
		for (int i = 0; i < a.length; i++)
		{
			int x=sum^a[i];
			if (x<a[i])
			{//不能超过堆的大小
				System.out.println(a[i]+"->"+x);
			}
		}
	}
}



  • 欧几里得定理扩展
算术基本定理 质因数分解的唯一性  求最大公约数与最小公倍数
有两个数 a b,现在,我们要求 a b 的最大公约数,怎么求?枚举他们的因子?不现实,当 a b 很大的时候,枚举显得那么的naïve ,那怎么做?
最大公约数:
    欧几里德有个十分又用的定理: gcd(a, b) = gcd(b , a%b)
道理:一个数能除开A B ,也就能除开 A-B A+B

最小公倍数: 
(A*B)/最大公约数gcd

Biginteger就有





[4.2 真题:天平称重]
用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量。
如果只有5个砝码,重量分别是1,3,9,27,81
则它们可以组合称出1到121之间任意整数重量(砝码允许放在左右两个盘中)。

本题目要求编程实现:对用户给定的重量,给出砝码组合方案。
例如:
用户输入:
5
程序输出:
9-3-1
用户输入:
19
程序输出:
27-9+1

要求程序输出的组合总是大数在前小数在后。
可以假设用户的输入的数字符合范围1~121。

package 数论;

import java.util.Scanner;

public class 天平称重
{
	static int n;
	private static Scanner scanner;
	public static void main(String[] args)
	{
//		scanner = new Scanner(System.in);
//		n=scanner.nextInt();
//		int x[]={1,3,9,27,81};
//		f(x,0,0,"");
		
		f2(19);
	}

	private static void f2(int i)
	{
		int a=i%3;
		if (i==0)
		{
			return;
		}
		if (a==2)
		{
			f2((i+1)/3);
			a=-1;
		}
		else {
			f2(i/3);
		}
		System.out.print(a);
	}

	private static void f(int[] x, int i,int count,String string)
	{
		if (i==x.length)
		{
			if (count==n)
			{
				if (string.charAt(0)=='+')
				{
					string=string.substring(1);
				}
				System.out.println(string);
			}
			return;
		}
		
		for (int j = -1; j <=1; j++)
		{
			
			if (j==-1)
			{
				f(x, i+1, count+j*x[i], new String(j*x[i]+string));
			}
			if (j==0)
			{
				f(x, i+1, count+j*x[i], new String(string));
			}
			if (j==1)
			{
				f(x, i+1, count+j*x[i], new String("+"+(j*x[i])+string));
			}
		}
	}
}


[4.4 真题:一步之遥]
从昏迷中醒来,小明发现自己被关在X星球的废矿车里。
矿车停在平直的废弃的轨道上。
他的面前是两个按钮,分别写着“F”和“B”。

小明突然记起来,这两个按钮可以控制矿车在轨道上前进和后退。
按F,会前进97米。按B会后退127米。
透过昏暗的灯光,小明看到自己前方1米远正好有个监控探头。
他必须设法使得矿车正好停在摄像头的下方,才有机会争取同伴的援助。
或许,通过多次操作F和B可以办到。

矿车上的动力已经不太足,黄色的警示灯在默默闪烁...
每次进行 F 或 B 操作都会消耗一定的能量。
小明飞快地计算,至少要多少次操作,才能把矿车准确地停在前方1米远的地方。

请填写为了达成目标,最少需要操作的次数。

不定方程 97X+127Y=1
                            Ax +B y=1
扩展欧几里得定理 Ax+By=gcd(A,B)有解
同理为          Ax+By=gcd(B,A%B)

A=(A/B)*B + A % B //除数+余数
就得 ((A/B)*B + A % B)x +B y=gcd(B,A%B)
B( (A/B) (x+y) )+(A % B)x=gcd(B,A%B)
( (A/B) (x+y) )=x1
x=y1
 B x1+A%B y1 =gcd(B,A%B)
可得
x=y1
y=x1-A/B*y1

package 数论;

public class 欧几里得最大公约数最小公倍数定理及其扩展
{

	public static void main(String[] args)
	{
//		System.out.println(gcd(40, 20));
//		System.out.println(lcm(50, 20));
		int A=97;int B=127;
		int []xy=new int [2];
		e_gcd(A,B,xy);
		System.out.println(xy[0]+"  "+xy[1]);
	}
	/*
	 * 欧几里得扩展 解不定方程
	 * 不定方程 A * X+B * Y = gcd(A,B)
	 * 					 = gcd(B,A%B)
	 * ((A/B)*B + A % B)x +B y
	 * B* (A/B * x + y )+(A%B) * x=gcd(B,A%B)
	 * x=新y
	 * y=新x-A/B*新y
	 */
	private static int e_gcd(int a, int b, int[] xy)
	{
		if (b==0)
		{
			xy[0]=1;
			xy[1]=0;
			return a;
		}
		int ans=e_gcd(b, a%b, xy);
		int temp=xy[0];
		xy[0]=xy[1];//x=新y
		xy[1]=temp-a/b*xy[0];//y=新x-A/B*新y
		return ans;
	}

	//最小公倍数: (A*B)/最大公约数
	public static int lcm(int a,int b)
	{
		return (a*b)/gcd(a, b);
	}
	
	//欧几里德有个十分又用的定理: gcd(a, b) = gcd(b , a%b)
	public static int gcd(int a,int b)
	{
		if (b==0)
		{
			return a;
		}
		return gcd(b, a%b);
	}

}




4.6 作业:素数表
素数的筛法
第1个素数是2,第2个素数是3,...
求第100002(十万零二)个素数

package 数论;

public class 筛选法求素数
{

	public static void main(String[] args)
	{
		int N=1500*1000;
		int x=100002;
		byte arr[]=new byte[N];
		for (int i = 2; i < N/2; i++)
		{
			if (arr[i]==1)
			{
				continue;
			}
			for (int j = 2; j <= N/i; j++)
			{
				if (i*j<N)
				{
					arr[i*j]=1;
				}
			}
		}
		
		int count=0;
		for (int i = 2; i < arr.length; i++)
		{
			if (arr[i]!=1)
			{
				count++;
				if (count==x)
				{
					System.out.println(i);
				}
			}
		}
		System.out.println(count);
	}

}


大数学家高斯有个好习惯:无论如何都要记日记。
他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210

后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?

高斯出生于:1777年4月30日。
在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。

高斯获得博士学位的那天日记上标着:8113
请你算出高斯获得博士学位的年月日。
A-B = A - 基准 - (B - 基准)
package 数论;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class 日期差问题
{
	// 2015-3-2 距离 1979-12-15多少天
	/**
	 *  1 将日期格式的字符串转成Date对象
	 *  2 将Date对象转成毫秒值 
	 *  3 相减变成天数
	 * 
	 * @param args
	 * @throws ParseException
	 */
	public static void main(String[] args) throws ParseException
	{
		test("2015-3-2", "1979-12-15");

	}

	private static void test(String str_date1, String str_date2) throws ParseException
	{
		// 1 将日期字符串转成日期对象。
		// 定义日期格式对象。
		DateFormat dateFormat = DateFormat.getDateInstance();
		dateFormat = new SimpleDateFormat("yyyy-MM-dd");

		//1 将日期格式的字符串转成Date对象
		Date date1 = dateFormat.parse(str_date1);
		Date date2 = dateFormat.parse(str_date2);

		//2 将Date对象转成毫秒值 
		long time1 = date1.getTime();
		long time2 = date2.getTime();
		
		long time = Math.abs(time2 - time1);
		
		//3 相减变成天数
		int day = getDay(time);
		System.out.println(day);

	}

	private static int getDay(long time)
	{
		int day = (int) (time / 1000 / 60 / 60 / 24);
		return day;
	}
}


  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《析与概率数论导引》是一本介绍析和概率数论的导引性书籍。析和概率数论是数学中的两个重要分支,通过本书的学习可以初步了这两个领域的基本概念和方法。 首先,本书从数论方面入手,介绍了数论的基本概念和方法。数论是研究数论问题的一种方法,它借助析方法和复变函数的理论来研究数论中的一些问题。本书详细介绍了数论中的一些基本概念,例如高斯和黎曼等函数,以及析逼近和数论中的一些定理和猜想,如黎曼猜想。 其次,本书还涉及了概率数论的内容。概率数论是概率论和数论的结合,研究了数论中的随机性质和随机现象。本书介绍了概率数论中的一些基本概念,如离散随机变量和连续随机变量,以及概率数论中的一些常用定理和技巧,如拉普拉斯定理和特征函数的应用等。 通过学习本书,读者可以初步了析和概率数论的基本概念和方法,对这两个领域有一个整体的认识。此外,本书还提供了一些习题和案例分析,帮助读者更好地理和应用所学知识。 总之,《析与概率数论导引》是一本介绍析和概率数论的导引性书籍,通过学习本书可以初步了析和概率数论的基本概念和方法,对这两个领域有一个整体的认识。这对于对析和概率数论感兴趣的读者来说是一本很有价值的学习资料。 ### 回答2: 《析与概率数论导引》是一本介绍析与概率数论基础知识的PDF文件。这本导引首先介绍了析的基本概念和理论,包括复数域上的析函数、柯西—黎曼方程及其应用、析函数的级数展开等。进一步,导引还涉及到析函数的性质,如极值原理、最大模原理等。这些知识为理析函数的基本特性提供了基础。 其次,导引也包含了对概率数论基础的介绍。概率数论是数学中的一个重要分支,主要研究随机事件及其数学性质。这本导引详细介绍了概率论的基本概念和原理,包括事件、概率、条件概率、随机变量等。在此基础上,导引进一步阐述了期望、方差、随机过程等概念,以及它们的计算方法和性质。 通过析与概率数论导引,读者可以获得析与概率数论的基础知识。这些知识在数学理论研究和实际问题中有着广泛的应用,尤其在统计学、金融学、计算机科学等领域中发挥着重要作用。同时,导引中还涉及了一些实际例子和习题,帮助读者巩固所学知识。 总结起来,析与概率数论导引PDF是一本介绍析与概率数论基础知识的资料。通过阅读此导引,读者可以系统地学习析函数和概率数论的基本理论和应用。这对于提高数学素养、决实际问题具有重要意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值