在焦作站的acm网络赛中遇到了一个高精度开根的水题……但是那时候WA了

后面学写java补题还T了orz

所以写一篇文章来记录一下java的大整数类型的基础和开根还有一点心得体会吧

首先给那一题的题面和模板

Jessie and Justin want to participate in e-sports. E-sports contain many games, but they don't know which one to choose, so they use a way to make decisions.

They have several boxes of candies, and there are ii candies in the i^{th}ith box, each candy is wrapped in a piece of candy paper. Jessie opens the candy boxes in turn from the first box. Every time a box is opened, Jessie will take out all the candies inside, finish it, and hand all the candy papers to Justin.

When Jessie takes out the candies in the N^{th}Nth box and hasn't eaten yet, if the amount of candies in Jessie's hand and the amount of candy papers in Justin's hand are both perfect square numbers, they will choose Arena of Valor. If only the amount of candies in Jessie's hand is a perfect square number, they will choose Hearth Stone. If only the amount of candy papers in Justin's hand is a perfect square number, they will choose Clash Royale. Otherwise they will choose League of Legends.

Now tell you the value of NN, please judge which game they will choose.

Input

The first line contains an integer T(1 \le T \le 800)T(1≤T≤800) , which is the number of test cases.

Each test case contains one line with a single integer: N(1 \le N \le 10^{200})N(1≤N≤10200) .

Output

For each test case, output one line containing the answer.

传送门:https://nanti.jisuanke.com/t/31719

样例输入复制

  1. 4
  2. 1
  3. 2
  4. 3
  5. 4

样例输出复制

  1. Arena of Valor
  2. Clash Royale
  3. League of Legends
  4. Hearth Stone

题目来源

 1 import java.math.BigInteger;
2 import java.util.Scanner;
3 import java.util.TreeSet;
4
5 public class Main
6 {
7
8 static BigInteger n,mod;
9 public static BigInteger Sqrt(BigInteger c)
10 {
11 if(c.compareTo(BigInteger.ONE)<=0)//0返回0 1返回1
12 return c;
13
14 BigInteger temp=null,x;
15 x=c.shiftRight((c.bitLength()+1)/2);//初始猜值为二进制右移至位数只剩一半
16 while(true)//以下为牛顿迭代法
17 {
18 temp=x;
19 x=x.add(c.divide(x)).shiftRight(1);
20 if(temp.equals(x)||x.add(BigInteger.ONE).equals(temp))//两次迭代相等或只差一
21 break;
22 }
23 return x;
24 }
25 public static boolean judge(BigInteger c)
26 {
27 BigInteger x=Sqrt(c);
28 if(x.multiply(x).equals(c))//平方回去是否还是本身
29 return true;
30 else
31 return false;
32 }
33 public static void main(String[] args)
34 {
35 Scanner sc=new Scanner(System.in);
36 int t=sc.nextInt();
37 while(t>0)
38 {
39 t--;
40 n=sc.nextBigInteger();
41 boolean x,y;
42 x=judge(n);
43 y=judge(n.multiply(n.subtract(BigInteger.ONE)).shiftRight(1));
44 if(x&&y)
45 System.out.println("Arena of Valor");
46 else if(!x&&y)
47 {
48 System.out.println("Clash Royale");
49 }
50 else if(x&&!y)
51 {
52 System.out.println("Hearth Stone");
53 }
54 else
55 {
56 System.out.println("League of Legends");
57 }
58 }
59 }
60 }

这个还是比较好理解的,但是在自己用同样思路写的时候就T了。有几个细节可以优化:

  1. 除二(divide(two)) 用算术右移shiftRight(1) 可以快很多很多
  2. 还有就是通过数学方法 这题里面有个n*(n-1)/2 是可以简化的

然后还有就是一些别人的判定方法

 1 public static boolean check(BigInteger now){
2 if (now.compareTo(BigInteger.ZERO) == 0 || now.compareTo(BigInteger.ONE) == 0) return true;//同样的特判0,1,2,3
3 if (now.mod(BigInteger.valueOf(3)).compareTo(BigInteger.valueOf(2)) == 0) return false;
4
5
6 String s = now.toString();
7 if(s.length()%2==0) s = s.substring(0,s.length()/2+1);
8 else s = s.substring(0,(1+s.length())/2);//也是拆成一半
9
10 BigInteger res = BigInteger.ZERO;
11 BigInteger m = new BigInteger(s);
12 BigInteger two = new BigInteger("2");
13 if(s == "1") res = BigInteger.ONE;
14 else{
15 while(now.compareTo(m.multiply(m)) < 0){
16 m = (m.add(now.divide(m))).divide(two);
17 }
18 res = m;
19 }
20
21 if (res.multiply(res).compareTo(now) == 0) return true;
22 return false;
23 }

从这个可以看出 牛顿迭代法的起始非常重要。

还有最后一点点。。这题可以通过数学方法简化(n-1)*n/2的规模,同样可以不T噢~

最后再存一点点java高精度常用的东西吧

import java.util.*;
import java.io.*;
import java.math.*; import java.math.*; public class Main { public static BigInteger sqrt2(BigInteger x) {
BigInteger div = BigInteger.ZERO.setBit(x.bitLength()/2);
BigInteger div2 = div;
// Loop until we hit the same value twice in a row, or wind
// up alternating.
for(;;) {
BigInteger y = div.add(x.divide(div)).shiftRight(1);
if (y.equals(div) || y.equals(div2))
return y;
div2 = div;
div = y;
}
}
public static void main(String []args) { Scanner sc=new Scanner(System.in);
BigInteger a=sc.nextBigInteger();
BigInteger b=sc.nextBigInteger();
int n=sc.nextInt();
BigInteger c=BigInteger.ONE;
BigDecimal d=sc.nextBigDecimal();
BigInteger e=sc.nextBigInteger();
String str=sc.nextLine(); /*
//d为int型,a,b,c都为大数
c=a.add(b); // 相加
c=a.subtract(b); // 相减
c=a.multiply(b); // 相乘
c=a.divide(b); // 相除取整 用shiftRight(1)快很多
c=a.gcd(b); // 最大公约数
c=a.remainder(b); // 取余
c=a.mod(b); // a mod b
c=a.abs(); // a的绝对值
c=a.negate(); // a的相反数
c=a.pow(d); // a的b次幂 d为int型
c=a.max(b); // 取a,b中较大的
c=a.min(b); // 取a,b中较小的
d=a.compareTo(b); // 比较a与b的大小 d=-1小于 d=0等于 d=1大于 d为int型
a.equals(b); // 判断a与b是否相等 相等返回true 不相等返回false
*/ //加减乘除add,subtract,multiply,divide
System.out.println(a.add(b));
System.out.println(a.subtract(b));
System.out.println(a.multiply(b));
System.out.println(a.divide(b)); //阶乘
//注意BigInteger.valueOf()的使用
for(int i=1;i<=n;i++) {
c=c.multiply(BigInteger.valueOf(i));
}
System.out.println(c);
//比较大小
int flag=a.compareTo(b);
if(flag==-1) {
System.out.println("a<b");
} else if(flag==0) {
System.out.println("a=b");
} else {
System.out.println("a>b");
}
//高精度幂
//stripTrailingZeros():返回数值上等于此小数,但从该表示形式移除所有尾部0的BigDecimal
//toPlainString():将BigDecimal转换为字符串
//stratswith("c"):判断该字符串是不是以字符c开头的
//substring(st,en):返回该字符串减去下标在[st,en)的字符串
String res=d.pow(n).stripTrailingZeros().toPlainString();
if(res.startsWith("0")) {
res=res.substring(0,1);
}
System.out.println(res);
//大数的进制转换
//先将字符串转化为10进制大数,然后将大数转化为2进制字符串
e=new BigInteger(str,10);
String tmp=e.toString(2);
/*
d=a.intValue(); // 将大数a转换为 int 类型赋值给 d
e=a.longValue(); // 将大数a转换为 long 类型赋值给 e
f=a.floatValue(); // 将大数a转换为 float 类型赋值给 f
g=a.doubleValue(); // 将大数a转换为 double 类型赋值给 g
s=a.toString(); // 将大数a转换为 String 类型赋值给 s
a=BigInteger.valueOf(e); // 将 e 以大数形式赋值给大数 a e只能为long或int
*/
sc.close();
}
}

谢谢ACM贴吧交流群和bin巨的ACM交流群的巨巨们指导啦~

还有就是 CSDN上和stackoverflow的博主们啦

Java高精度基础+开根的更多相关文章

  1. BZOJ 高精度开根 JAVA代码

    晓华所在的工作组正在编写一套高精度科学计算的软件,一些简单的部分如高精度加减法.乘除法早已写完了,现在就剩下晓华所负责的部分:实数的高精度开m次根.因为一个有理数开根之后可能得到一个无理数,所以这项工 ...

  2. Android开发之Java必备基础

    Android开发之Java必备基础 Java类型系统 Java语言基础数据类型有两种:对象和基本类型(Primitives).Java通过强制使用静态类型来确保类型安全,要求每个变量在使用之前必须先 ...

  3. codevs 3119 高精度练习之大整数开根 (各种高精+压位)

    /* codevs 3119 高精度练习之大整数开根 (各种高精+压位) 二分答案 然后高精判重 打了一个多小时..... 最后还超时了...压位就好了 测试点#1.in 结果:AC 内存使用量: 2 ...

  4. [code3119]高精度练习之大整数开根

    试题描述  给出一个正整数n,求n开根号后的整数部分的值.n的位数不超过1000位. 输入 读入一个不超过1000位的正整数n. 输出 输出所求答案 输入示例 17   输出示例 4 高精度开根:需要 ...

  5. 【BZOJ1213】高精度开根

    python是坠吼的! 原题: 不贴原题,就是高精度开根,结果向下取整 首先二分答案,高精度嘛……python即可 二分右端点设为n会T掉,需要先倍增一个r,while(r **m <= n) ...

  6. java在线聊天项目 实现基本聊天功能后补充的其他功能详细需求分析 及所需要掌握的Java知识基础 SWT的激活方法,swt开发包下载,及破解激活码

    补充聊天项目功能,做如下需求分析: 梳理项目开发所需的必要Java知识基础 GUI将使用更快速的swt实现 SWT(Standard Widget Toolkit) Standard Widget T ...

  7. BZOJ 1213: [HNOI2004]高精度开根

    二次联通门 : BZOJ 1213: [HNOI2004]高精度开根 正解 NTT+高精+倍增+二分 但是可以用python 2333333 m,n=int(raw_input()),int(raw_ ...

  8. [转]Java多线程干货系列—(一)Java多线程基础

    Java多线程干货系列—(一)Java多线程基础 字数7618 阅读1875 评论21 喜欢86 前言 多线程并发编程是Java编程中重要的一块内容,也是面试重点覆盖区域,所以学好多线程并发编程对我们 ...

  9. JAVA面试基础

    JAVA相关基础知识1.面向对象的特征有哪些方面 ?1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂 ...

随机推荐

  1. 菜鸡的Java笔记 - java 线程的同步与死锁 (同步 synchronization,死锁 deadlock)

    线程的同步与死锁 (同步 synchronization,死锁 deadlock)        多线程的操作方法            1.线程同步的产生与解决        2.死锁的问题     ...

  2. [atAGC050B]Three Coins

    记$p_{i}$表示该位置是否有硬币 称使得$p_{i,i+1,i+2}$都变为1的操为对$i$的添加操作,使得$p_{i,i+1,i+2}$都变为0的操作为对$i$的删除操作 考虑一个简单的操作:若 ...

  3. layui的入门使用

    1.如果使用单独的layui插件的话需要先引入jquery的插件,官方建议1.8+的版本. 2.引入后就能根据规则正常使用了.

  4. (前端)面试300问之(3)this的指向判断

    一.this的相关理解与解读 1.各角度看this. 1)ECMAScript规范: this 关键字执行为当前执行环境的 ThisBinding. 2)MDN: In most cases, the ...

  5. 【2020-8-21】【数字游戏】【启发式搜索IDA*】

    有这么一个游戏: 写出一个1-N的排列a[i],然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少1,直到只剩下一个数字位置.下面是一个例子: ...

  6. CF1463E Plan of Lectures

    考虑我们两种操作: 我们把第一种操作在\(x\to y\)连一条权为-1的边. 第二种操作\(x\to y\)连-1,\(y\to x\)连1的边. 当无法操作则是环里有负环. 否则我们把第二种操作涉 ...

  7. Oracle JDK 下载、配置与验证

    # 1. 解决官网下载JDK需要登录Oracle账号问题(JDK 8) JDK 1.8 官网下载地址: https://www.oracle.com/java/technologies/javase/ ...

  8. window修改dns本地文件

    文件地址: C:\Windows\System32\drivers\etc 先修改权限: 最后用记事本打开编辑保存即可

  9. 压力测试工具——apchebench(简称ab)

    ab的原理 ab的原理:ab命令会创建多个并发访问线程,模拟多个访问者同时对某一URL地址进行访问.它的测试目标是基于URL的,因此,它既可以用来测试apache的负载压力,也可以测试nginx.li ...

  10. rabbit mq的php使用 php-amqplib操作消息队列

    rabbit mq的php使用 php-amqplib操作消息队列 有大神翻译的教程,非常清楚可以参考: https://xiaoxiami.gitbook.io/rabbitmq_into_chin ...