csuoj 1114: 平方根大搜索
http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1114
1114: 平方根大搜索
Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 118 Solved: 60
[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
分析;
数字比较大,开始打算用数组模拟,WA啦,后来想到用Java的BigDecimal类实现(可是还是没有实现,因为BigDecimal开根号不能实现,后来看别人用函数模拟了一个)。
AC代码:
C++版:
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <sstream> 5 #include <algorithm> 6 #include <cmath> 7 using namespace std; 8 int a1[10010],a2[10010],b[10000],c[10000],l1,l2,s[110000]; 9 int l3,l4,l5,point,point2,point3,point1; 10 char ans[1000]; 11 char ss[23]; 12 int chengfa() 13 { 14 int pos,i,j; 15 memset(s,0,sizeof(s)); 16 for (i=1;i<=l4;i++) 17 for (j=1,pos=i;j<=l4;j++) 18 s[pos++]+=a2[i]*a2[j]; 19 pos-=1; 20 for (i=1;i<=pos;i++) 21 if (s[i]>=10) 22 { 23 if (i==pos) pos++; 24 s[i+1]+=s[i]/10; 25 s[i]%=10; 26 } 27 return pos; 28 } 29 void jia() 30 { 31 int p=1,i; 32 if (point > point1) 33 { 34 for (i=1;i<=point - point1;i++) 35 a2[p++]=a1[i]; 36 int tt=1; 37 for (i=point - point1+1;i<=l1;i++) 38 a2[p++]=a1[i]+c[tt++]; 39 point2=point; 40 } 41 else 42 { 43 for (i=1;i<=point1-point;i++) 44 a2[p++]=c[i]; 45 int tt=i; 46 for (i=1;i<=l1;i++) 47 a2[p++]=a1[i]+c[tt++]; 48 point2=point1; 49 } 50 int kk=0; 51 p--; 52 for (i=1;i<=p;i++) 53 { 54 a2[i]+=kk; 55 kk=a2[i]/10; 56 a2[i]%=10; 57 } 58 if (kk!=0) a2[++p]=kk; 59 l4=p; 60 } 61 int gobj() 62 { 63 int sl=l5,bl=l2; 64 if (sl-point3>bl) return 1; 65 else if (sl-point3<bl) return -1; 66 while (sl>0 && bl>0) 67 { 68 if (s[sl]>b[bl]) return 1; 69 if (s[sl]<b[bl]) return -1; 70 sl--;bl--; 71 } 72 if (sl==0) return 0; 73 else return 1; 74 } 75 int main() 76 { 77 int T,n; 78 scanf("%d",&T); 79 while (T--) 80 { 81 memset(ans,0,sizeof(ans)); 82 memset(a1,0,sizeof(a1)); 83 memset(a2,0,sizeof(a2)); 84 memset(c,0,sizeof(c)); 85 memset(b,0,sizeof(b)); 86 scanf("%d",&n); 87 getchar(); 88 scanf("%s",&ss); 89 int m=sqrt(n); 90 int mm=m; 91 int j=1; 92 l1=0; 93 point=0; 94 while (mm) 95 { 96 a1[j++]=mm % 10; 97 mm/=10; 98 l1++; 99 } 100 point=0; 101 mm=n; 102 j=1;l2=0; 103 while (mm) 104 { 105 b[j++]=mm%10; 106 mm/=10; 107 l2++; 108 } 109 c[1]=1;l3=1; 110 int i; 111 for (i=1;i<=130;i++) 112 { 113 for (j=1;j<=l3;j++) 114 c[j]*=5; 115 int kk=0; 116 for (j=1;j<=l3;j++) 117 { 118 c[j]+=kk; 119 kk=c[j]/10; 120 c[j]=c[j]%10; 121 } 122 if (kk) c[++l3]=kk; 123 point1=i; 124 jia(); 125 /*for (j=l4;j>0;j--) 126 { 127 if (point2==j) cout<<"."; 128 printf("%d",a2[j]); 129 } 130 cout<<endl;*/ 131 l5=chengfa(); //平方后长度 132 point3=2*point2; //平方后小数点位置 133 /*for (j=l5;j>0;j--) 134 { 135 if (point3==j) cout<<"."; 136 printf("%d",s[j]); 137 } 138 cout<<endl;*/ 139 int re=gobj(); 140 if (re==1) //1:s>b -1:s<b 141 ans[i-1]='0'; 142 else if (re==-1) 143 { 144 ans[i-1]='1'; 145 memset(a1,0,sizeof(a1)); 146 for (j=1;j<=l4;j++) 147 a1[j]=a2[j]; 148 l1=l4; 149 point=point2; 150 } 151 else break; 152 } 153 for (j=i;j<=130;j++) 154 ans[i]='0'; 155 ans[130]='\0'; 156 //cout<<ans<<endl; 157 cout<<strstr(ans,ss) - ans << endl; 158 } 159 return 0; 160 }
Java版:
1 import java.util.*; 2 import java.math.*; 3 public class Main { 4 static String tob(BigDecimal d) 5 { 6 String s=new String(); 7 int n=150; 8 while(!d.equals(BigDecimal.ZERO)&&n--!=0) 9 { 10 d=d.multiply(BigDecimal.valueOf(2)); 11 BigInteger x=d.toBigInteger(); 12 s+=x; 13 d=d.subtract(BigDecimal.valueOf(x.longValue())); 14 } 15 return s; 16 } 17 public static BigDecimal culsqrt(int num) 18 { 19 20 21 return sqrtMathod(num); 22 23 } 24 25 26 public static BigDecimal sqrtMathod(int num) 27 { 28 BigDecimal sqrtNum = BigDecimal.valueOf(-1); 29 boolean isFindSqrt = false; 30 31 32 // get int sqrt num 33 double tempSqrt = 0; 34 if (num > 0) 35 { 36 if (num == 1) 37 { 38 return BigDecimal.valueOf(1); 39 } 40 else 41 { 42 for (int j = 0; j <= num / 2 + 1; j++) 43 { 44 if (j * j == num) 45 { 46 sqrtNum = BigDecimal.valueOf(j); 47 isFindSqrt = true; 48 break; 49 } 50 if (j * j > num) 51 { 52 tempSqrt = j - 1; 53 break; 54 } 55 } 56 } 57 } 58 59 60 if (!isFindSqrt) 61 { 62 sqrtNum = recuFindSqrt(num, BigDecimal.valueOf(tempSqrt), isFindSqrt, BigDecimal.valueOf(1)); 63 } 64 65 66 return sqrtNum; 67 } 68 69 70 private static BigDecimal recuFindSqrt(int num, BigDecimal sqrtValue, boolean isFindSqrt, BigDecimal ac) 71 { 72 ac = ac.multiply(BigDecimal.valueOf(10)); 73 BigDecimal tempSqrt = BigDecimal.valueOf(0); 74 for (int i = 0; i < 10; i++) 75 { 76 tempSqrt = sqrtValue .add(BigDecimal.valueOf(i).divide(ac) ); 77 if (tempSqrt .multiply(tempSqrt) .equals(BigDecimal.valueOf(num))) 78 { 79 isFindSqrt = true; 80 sqrtValue = tempSqrt; 81 } 82 else if (tempSqrt .multiply(tempSqrt) .compareTo(BigDecimal.valueOf(num))==1) 83 { 84 tempSqrt = sqrtValue.add(BigDecimal.valueOf(i - 1) .divide( ac)); 85 sqrtValue = tempSqrt; 86 break; 87 } 88 } 89 90 91 BigDecimal temp = tempSqrt; 92 if (temp.toString().length() <= 150 && !isFindSqrt) 93 { 94 sqrtValue = recuFindSqrt(num, tempSqrt, isFindSqrt, ac); 95 } 96 97 98 return sqrtValue; 99 } 100 101 102 public static double add(double v1, double v2) 103 { 104 BigDecimal b1 = new BigDecimal(Double.toString(v1)); 105 BigDecimal b2 = new BigDecimal(Double.toString(v2)); 106 return b1.add(b2).doubleValue(); 107 } 108 109 public static void main(String[] args) { 110 Scanner in= new Scanner(System.in); 111 int t; 112 int n; 113 String st; 114 t=in.nextInt(); 115 while(t--!=0) 116 { 117 n=in.nextInt(); 118 st=in.next(); 119 BigDecimal d=culsqrt(n); 120 BigInteger x=d.toBigInteger(); 121 d=d.subtract(BigDecimal.valueOf(x.longValue())); 122 String tobs=tob(d); 123 System.out.println(tobs.indexOf(st)); 124 } 125 } 126 }
悠游天地间 all rights reserved. © 2013 -- 1 << 64