zoukankan      html  css  js  c++  java
  • UVa 12505 Searching in sqrt(n)

    传送门

    一开始在vjudge上看到这题时,标的来源是CSU 1120,第八届湖南省赛D题“平方根大搜索”。今天交题时CSU突然跪了,后来查了一下看哪家OJ还挂了这道题,竟然发现这题是出自UVA的,而且用的原题。


    Description

    time limit 5s

    In binary, the square root of 2, denoted by sqrt(2), is an infinite number 1.0110101000001001111... Given an integer n and a binary string (i.e. a string consisting of 0 and 1) S, your task is to find the first occurrence of S in the fraction part (i.e. the part after the decimal point) of sqrt(n). In case sqrt(n) is an integer, the fraction part is an infinite sequence of zeros.

    Input

    The first line contains T (T ≤ 100), the number of test cases. Each of the following lines contains an integer n (2 ≤ n ≤ 1, 000, 000) and a binary string S with at most 20 characters.

    Output

    For each case, print the position of the first character in the first occurrence of S. The first digit after the dot is at position 0. The answer is guaranteed to be no greater than 100.

    Sample Input

    2

    2 101

    1202 110011

    Sample Output

    2

    58

    Solution

    高精度

    复杂度 $O(n^3)$

     

    #include <bits/stdc++.h>
    using namespace std;
    const int N(300), M(125);
    int get_len(int n){
        if(!n) return 1;
        int res=0;
        for(;n;res++,n>>=1);
        return res;
    }
    void trans(int n, int *bit, int &len){
        int l=get_len(n);
        for(int i=len+l-1; i>=len; i--){
            bit[i]=n&1, n>>=1;
        }
        len+=l;
    }
    int tmp[N], a[N], b[N], len, _len, LEN;
    void sqr(){ //error-prone
        memset(tmp, 0, sizeof(tmp));
        for(int i=0; i<len; i++) for(int j=0; j<len; j++) tmp[i+j]+=a[i]*a[j];
        for(int i=2*len-2; i; i--){
            tmp[i-1]+=tmp[i]/2;
            tmp[i]%=2;
        }
        trans(tmp[0], b, LEN=0);
        for(int i=1; i<=2*len-2; i++) b[LEN++]=tmp[i];
    }
    int get_int(){
        int res=0, l=LEN-2*_len;
        for(int i=l-1, _pow=1; i>=0; res+=b[i]*_pow, i--, _pow<<=1);    //error-prone
        return res;
    }
    int solve(){
        int n; string s, t; cin>>n>>t;
        int m=sqrt(n);
        if(m*m==n) return 0;
        len=_len=0;
        trans(m, a, len);
        int tmp=len;
        while(_len<M){
            a[len++]=1, _len++;
            sqr();
            if(get_int()>=n) a[len-1]=0;
        }
        for(int i=tmp; i<len; i++) s+='0'+a[i]; 
        return s.find(t);
    }
    int main(){
        //freopen("in", "r", stdin);
        int T;
        for(cin>>T; T--; cout<<solve()<<endl);
    }
    

    有意写得短一些,但还是有50行,太长了都不想看~

    总结

    总结一下高精度度乘法的写法,虽说也没什么可总结的。

    无论二进制还是十进制,写法都一样,以下代码结合题目按二进制写。

    1. 大整数的存法:int[]数组,左边高位(左高右低即书写格式,这样处理有一定优越性(真的有优越性吗?)),0-indexed

    2. 将长为n的大整数的a[]和长为m的大整数的b[]相乘

    先按如下方式将长为n+m-1中间结果存在数组tmp[]

    memset(tmp, 0, sizeof(tmp));
    for(int i=0; i<n; i++)
        for(int j=0; j<m; j++)
            tmp[i+j]+=a[i]*b[j];
    

    再处理出最终结果存到数组c[]

    for(int k=i+j-2; k; k--)
        tmp[k-1]+=tmp[k]/2, tmp[k]%=2;
    
    int get_len(int n){
        if(!n) return 1;
        int res=0;
        for(; n; res++, n>>=1);
        return res;
    }
    
    len=get_len(tmp[0]);
    for(int i=len-1; i>=0; i--)
        c[i]=tmp[0]%2, tmp[0]/=2;
    
    for(int k=1; k<i+j-1; k++)
        c[len++]=tmp[k];
    
  • 相关阅读:
    深度学习练习(三)
    深度学习核心技术笔记(一)
    tensorflow的函数
    举例
    Tensorflow 笔记
    tensorflow框架
    基于python的感知机
    深度学习练习(一)
    深度学习练习(二)
    [javascript 实践篇]——那些你不知道的“奇淫巧技”
  • 原文地址:https://www.cnblogs.com/Patt/p/4743565.html
Copyright © 2011-2022 走看看