csuoj 1114: 平方根大搜索

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1114

1114: 平方根大搜索

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 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 }
View Code

 

 

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 }
View Code

 

你可能感兴趣的:(搜索)