zoukankan      html  css  js  c++  java
  • 湖南省第八届大学生计算机程序设计竞赛D题 平方根大搜索

      湖南省第八届大学生计算机程序设计竞赛D题 平方根大搜索(题目链接)。

    题目D   平方根大搜索

      在二进制中,2的算术平方根,即sqrt(2),是一个无限小数1.0110101000001001111...

      给定一个整数n和一个01串S,你的任务是在sqrt(n)的小数部分(即小数点之后的部分)中找出到S第一次出现的位置,如果sqrt(n)是整数,小鼠部分看作是无限个0组成的序列。

    输入格式

      输入第一行为数据组数T(T≤20)。以下每行为一组数据,仅包含一个整数n(2≤n≤1,000,000)和一个长度不超过20的非空01串S。

    输出格式

      对于每组数据,输出S的第一次出现中,第一个字符的位置。小数点后的第一个数字的位置为0。输入保证答案不超过100。

    样例输入

    2
    2 101
    1202 110011

    样例输出

    2
    50

      解题思路:二分法(对于二进制,其实就是0、1枚举法)。用bitset来储存二进制小数,用二分法算出x2-a=0的解。然后字符串匹配即可。C++语言代码如下:

    #include <cstdio>
    #include <cstdlib>
    #include <string>
    #include <cmath>
    #include <bitset>
    
    using namespace std;
    
    #define    MAX_LENGTH    2250
    #define    DECIMAL_DIGITS    1000
    #define    FAC_MAX_LENGTH    150
    #define FAC_DECIMAL_DIGITS    100
    
    typedef bitset <MAX_LENGTH> BigInt;
    typedef bitset <FAC_MAX_LENGTH> FacBigInt;
    
    BigInt operator+ ( const BigInt & a, const BigInt & b )
    {
        BigInt result;
        result.reset( );
        int temp;
        int carry = 0;
        for ( int i = MAX_LENGTH - 1; i >= 0 ; i -- )
        {
            temp = a[i] + b[i] + carry;
            carry = (temp >> 1);
            result[i] = (temp & 1);
        }
        return result;
    }
    
    BigInt & operator+= ( BigInt & a, const BigInt & b )
    {
        int temp;
        int carry = 0;
        for ( int i = 0; i < MAX_LENGTH ; i ++ )
        {
            temp = a[i] + b[i] + carry;
            carry = (temp >> 1);
            a[i] = (temp & 1);
        }
        return a;
    }
    
    bool operator> ( const BigInt & a, const BigInt & b )
    {
        for ( int i = MAX_LENGTH - 1 ; i >= 0 ; i -- )
        {
            if ( a[i] > b[i] )
                return true;
            else if ( a[i] < b[i] )
                return false;
        }
        return false;
    }
    
    inline BigInt FacBigIntToBigInt( const FacBigInt & n )
    {
        return BigInt(n.to_string()) << ( DECIMAL_DIGITS - FAC_DECIMAL_DIGITS );
    }
    
    BigInt & GetSq( const FacBigInt & n )
    {
        static BigInt result;
        result.reset( );
        BigInt m = FacBigIntToBigInt(n);
    
        for ( int i = DECIMAL_DIGITS - FAC_DECIMAL_DIGITS ; i < FAC_MAX_LENGTH + DECIMAL_DIGITS - FAC_DECIMAL_DIGITS ; i ++ )
        {
            if ( m[i] )
                result += ( m << i );
        }
        result >>= DECIMAL_DIGITS;
        return result;
    }
    
    FacBigInt & GetSqrt( const unsigned long input )
    {
        static FacBigInt mid;
    
        BigInt radicand = BigInt (input);
        BigInt square;
        radicand <<= DECIMAL_DIGITS;
    
        unsigned long intPart = static_cast<unsigned long>(sqrt(input));
    
        mid = intPart;
        mid <<= FAC_DECIMAL_DIGITS;
    
        if ( ( square = GetSq(mid) ) == radicand )
            return mid;
    
        for ( int i = FAC_DECIMAL_DIGITS - 1 ; i >= 0 ; i -- )
        {
            mid[i] = 1;
            if ( ( square = GetSq(mid) ) == radicand )
                break;
            else if ( square > radicand )
                mid[i] = 0;
        }
    
        return mid;
    }
    
    int main ( )
    {
        int test_cases;
        unsigned long input;
        char find_string[105];
        FacBigInt root;
        scanf( "%d", &test_cases );
        while ( test_cases -- )
        {
            scanf( "%lu", &input );
            root = GetSqrt( input );
            scanf( "%s", find_string );
            int pos = root.to_string().find(string(find_string),
                FAC_MAX_LENGTH - FAC_DECIMAL_DIGITS ) - (FAC_MAX_LENGTH - FAC_DECIMAL_DIGITS);
            printf( "%d\n", pos );
        }
        return EXIT_SUCCESS;
    }
  • 相关阅读:
    BZOJ.1468.Tree(点分治)
    BZOJ.1935.[SHOI2007]Tree园丁的烦恼(CDQ分治 三维偏序)
    BZOJ.4319.[cerc2008]Suffix reconstruction(后缀数组 构造 贪心)
    BZOJ.3262.陌上花开([模板]CDQ分治 三维偏序)
    洛谷.3374.[模板]树状数组1(CDQ分治)
    BZOJ.4566.[HAOI2016]找相同字符(后缀数组 单调栈)
    POJ.3145.Common Substrings(后缀数组 倍增 单调栈)
    POJ.2774.Long Long Message/SPOJ.1811.LCS(后缀数组 倍增)
    POJ.1743.Musical Theme(后缀数组 倍增 二分 / 后缀自动机)
    UOJ.35.[模板]后缀排序(后缀数组 倍增)
  • 原文地址:https://www.cnblogs.com/yejianfei/p/2725796.html
Copyright © 2011-2022 走看看