zoukankan      html  css  js  c++  java
  • 蓝桥杯练习系统 矩阵翻硬币 大数,牛顿迭代法 难度: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中的注解@see
    MacOS软件默认安装路径
    学习MACD指标
    go CD 用虚拟机快速增加一个新agent
    git推送本地分支到远程分支
    git如何切换远程仓库
    git命令查看远程分支
    Java 学习札记(一)JDK安装配置
    Oracle 基本操作符
    C# 常用控件属性及方法介绍
  • 原文地址:https://www.cnblogs.com/xuesu/p/4396114.html
Copyright © 2011-2022 走看看