csu 1114平方根大搜索(JAVA大小数+二分)
1114: 平方根大搜索
Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 182 Solved: 96
[Submit][Status][Web Board]
Description
在二进制中,2的算术平方根,即sqrt(2),是一个无限小数1.0110101000001001111...
给定一个整数n和一个01串S,你的任务是在sqrt(n)的小数部分(即小数点之后的部分)中找到S第一次出现的位置。如果sqrt(n)是整数,小数部分看作是无限多个0组成的序列。
Input
输入第一行为数据组数T (T<=20)。以下每行为一组数据,仅包含一个整数n (2<=n<=1,000,000)和一个长度不超过20的非空01串S。
Output
对于每组数据,输出S的第一次出现中,第一个字符的位置。小数点后的第一个数字的位置为0。输入保证答案不超过100。
Sample Input
2
2 101
1202 110011
Sample Output
2
58
HINT
Source
利用JAVA的大小数进行二分求解开方之后的数,设置标度为200,然后化成二进制进行匹配。
import java.math.BigDecimal; import java.util.Scanner; public class Main { final static BigDecimal eps = BigDecimal.valueOf(0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001); public static void main(String[] args) { Scanner sc = new Scanner(System.in); int tcase = sc.nextInt(); while(tcase-- > 0){ String str = sc.next(); String str1 = sc.next(); BigDecimal a = new BigDecimal(str); a.setScale(200); BigDecimal l = BigDecimal.ZERO; l.setScale(200); BigDecimal r = a; r.setScale(200); BigDecimal mid = new BigDecimal("0"); mid.setScale(200); while(l.add(eps).compareTo(r)<=0){ mid = l.add(r).divide(BigDecimal.valueOf(2)); if(mid.multiply(mid).compareTo(a)>0){ r = mid; }else{ l = mid; } } String s = mid.toString(); int idx = 0; for(int i=0;i<s.length();i++){ if(s.charAt(i)=='.'){ idx = i; break; } } s = s.substring(idx+1, s.length()); s = "0."+s; mid = new BigDecimal(s); String ans = ""; for(int i=1;i<=200;i++){ mid = mid.multiply(BigDecimal.valueOf(2)); if(mid.compareTo(BigDecimal.ONE)>=0){ ans+=1; mid = mid.subtract(BigDecimal.ONE); }else{ ans+=0; } } int res = ans.indexOf(str1); System.out.println(res); } } }