• 蓝桥杯练习系统 矩阵翻硬币 大数,牛顿迭代法 难度:2


    http://lx.lanqiao.org/problem.page?gpid=T126

    明显,对于一个格子(i,j),设f(i)为i的约数个数,则(i,j)的翻转次数为(f(i)-1)*(f(j)-1)+1,

    而只有翻转次数为奇数,也就是f(i),f(j)都为奇数的格子开始才是反面,

    又因为f(i)为奇数当且仅当i为完全平方数,所以只需统计n,m中各有多少个完全平方数,然后相乘即可,

    也就是sqrt(n)*sqrt(m),

    但是因为n,m是大数,必须要用大数方法解决,这里采用了java的BigInteger类,用牛顿迭代法逼近整数解.

    牛顿迭代法就是设y=f(x),设r是f(x)=0的解,x0是一个备用解,则y约等于f(x0)+f'(x0)*(x-x0),在已知y,f(x)的情况下,可从中解得x作为一级解,然后再填入该公式解出二级解,一直这么重复,解会越来越精确,可以证明如果f(x)是连续的,并且零点附近是孤立的,x会逐渐收敛在解r的附近

    对于这道题,设y=x^2,则y'=2*x,每次迭代中x=(y+x0*x0)/2/x0

    import java.math.BigDecimal;
    import java.math.BigInteger;
    import java.util.Scanner;
    
    
    public class Main {
    	static BigInteger mysqrt(BigInteger n){
    		BigInteger two=BigInteger.valueOf(2);
    		BigInteger l=BigInteger.ONE,r=(n.divide(l.multiply(two))).add(l.divide(two));
    		while(!l.equals(r)){
    			l=r;
    			r=(n.divide(l.multiply(two))).add(l.divide(two));
    			if(l.subtract(r).abs().equals(BigInteger.ONE))break;
    		}
    		while(l.multiply(l).compareTo(n)>0){
    			l=l.subtract(BigInteger.ONE);
    		}
    		while(l.add(BigInteger.ONE).multiply(l.add(BigInteger.ONE)).compareTo(n)<=0){
    			l=l.add(BigInteger.ONE);
    		}
    		return l;
    	}
    	public static void main(String[] args) {
    		BigInteger m,n;
    		Scanner scanner =new Scanner(System.in);
    		m=scanner.nextBigInteger();
    		n=scanner.nextBigInteger();
    		BigInteger nn=mysqrt(n);
    		BigInteger mm=mysqrt(m);
    		BigInteger ans = nn.multiply(mm);
    		System.out.println(ans);
    	}
    
    }
    
  • 相关阅读:
    Java帮助文档的生成
    Java内部类
    Java中利用标签跳出外层循环break
    【转】你真的了解word-wrap和word-break的区别吗?
    Office/Access 2013 扩展支持xbase/DBF 文件
    调用cmd.exe执行pdf的合并(pdftk.exe)
    input 数字输入控制(含小数)
    iis7.5 发布mvc出错的解决办法
    table中超过长度的列,显示省略号
    本地图片的预览和上传
  • 原文地址:https://www.cnblogs.com/xuesu/p/4396114.html
Copyright © 2020-2023  润新知