湖南省第八届大学生计算机程序设计竞赛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;
}
posted @ 2012-10-16 12:50  叶剑飞Victor  阅读(928)  评论(0编辑  收藏  举报