http://challenge.greplin.com/上的3道题。

最近写代码比较少,苦于没机会练手,就去找了一些编程网站,做几道题,昨晚发现http://challenge.greplin.com/有3道题,时间要求20分钟到3个小时,题目不难,把它完成了,贴出代码。


第一题,找出一长串字符串和其逆序串中,最长匹配字串。

#include "MoonString.h"


MoonString::MoonString(void)
{
}


MoonString::~MoonString(void)
{
}


string MoonString::Reverse(const string &srcString)
{
    size_t len = srcString.length();
    string outString;

    for(size_t i = 0; i < len; i++)
    {
        outString += srcString[len - i - 1];
    }

    return outString;
}


#pragma once

#include <string>
using namespace std;

class MoonString
{
public:
    MoonString(void);
    ~MoonString(void);

    
    //************************************
    // Method:    Reverse
    // Access:    public static 
    // Describe:  字符串逆序
    // Parameter: const string & srcString  要逆序的字符串
    // Returns:   std::string               逆序结果
    //************************************
    static string Reverse(const string &srcString);
};

/*

The Cue Programming Challenge

Level 1

----------------------------------------

Embedded in this block of text is the password for level 2.
The password is the longest substring that is the same in reverse.

As an example, if the input was "I like racecars that go fast"
the password would be "racecar".

Enter the password to access level 2:
*/

/*FourscoreandsevenyearsagoourfaathersbroughtforthonthiscontainentanewnationconceivedinzLibertyanddedicatedtothepropositionthatallmenarecreatedequalNowweareengagedinagreahtcivilwartestingwhetherthatnaptionoranynartionsoconceivedandsodedicatedcanlongendureWeareqmetonagreatbattlefiemldoftzhatwarWehavecometodedicpateaportionofthatfieldasafinalrestingplaceforthosewhoheregavetheirlivesthatthatnationmightliveItisaltogetherfangandproperthatweshoulddothisButinalargersensewecannotdedicatewecannotconsecratewecannothallowthisgroundThebravelmenlivinganddeadwhostruggledherehaveconsecrateditfaraboveourpoorponwertoaddordetractTgheworldadswfilllittlenotlenorlongrememberwhatwesayherebutitcanneverforgetwhattheydidhereItisforusthelivingrathertobededicatedheretotheulnfinishedworkwhichtheywhofoughtherehavethusfarsonoblyadvancedItisratherforustobeherededicatedtothegreattdafskremainingbeforeusthatfromthesehonoreddeadwetakeincreaseddevotiontothatcauseforwhichtheygavethelastpfullmeasureofdevotionthatweherehighlyresolvethatthesedeadshallnothavediedinvainthatthisnationunsderGodshallhaveanewbirthoffreedomandthatgovernmentofthepeoplebythepeopleforthepeopleshallnotperishfromtheearth*/

#include <iostream>
#include <windows.h>
#include <ctime>
#include <assert.h>

#include <string>
#include "MoonString.h"
using namespace std;


//************************************
// Method:    GetMaxSubString
// Access:    public
// Describe:  查找2个字符串中重叠的最长字符串
// Parameter: const string & str1
// Parameter: const string & str2
// Returns:   std::string
//************************************
string GetMaxSubString(const string &str1, const string &str2)
{
    size_t len = min(str1.length(), str2.length());
    size_t currLen = 0;
    size_t maxLen = 0;
    size_t maxSubStrStartIndex = 0;

    for(size_t i = 0 ; i < len; i++)
    {
        if(str1[i] == str2[i])
        {
            currLen++;

            if(currLen > maxLen)
            {
                maxLen = currLen;
                maxSubStrStartIndex = i - currLen + 1;
            }
        }
        else
        {
            currLen = 0;
        }
    }

    return str1.substr(maxSubStrStartIndex, maxLen);
}

//************************************
// Method:    GetMaxReverseSubString
// Access:    public 
// Describe:  字符串2固定,字符串1逐渐缩短,找到相同索引最长的字串
// Parameter: const string & str1
// Parameter: const string & str2
// Returns:   std::string
//************************************
string GetMaxReverseSubString(const string &str1, const string &str2)
{
    size_t len = str1.length();
    size_t maxLen = 0;
    size_t currLen = 0;
    string currSubStr;
    string maxSubStr;

    for(size_t i = 0; i < len; i++)
    {
        currSubStr = GetMaxSubString(str1.substr(i), str2);
        currLen = currSubStr.length();

        if(currLen > maxLen)
        {
            maxLen = currLen;
            maxSubStr = currSubStr;
        }
    }

    return maxSubStr;
}

void F1()
{
    cout << "void F1()" << endl;

    LARGE_INTEGER timeStart, timeEnd, freq;
    QueryPerformanceFrequency(&freq);
    QueryPerformanceCounter(&timeStart);

    /*********************************算法开始*******************************/

    //const string INPUT_TEXT = "123456789987654321";
    const string INPUT_TEXT = "FourscoreandsevenyearsagoourfaathersbroughtforthonthiscontainentanewnationconceivedinzLibertyanddedicatedtothepropositionthatallmenarecreatedequalNowweareengagedinagreahtcivilwartestingwhetherthatnaptionoranynartionsoconceivedandsodedicatedcanlongendureWeareqmetonagreatbattlefiemldoftzhatwarWehavecometodedicpateaportionofthatfieldasafinalrestingplaceforthosewhoheregavetheirlivesthatthatnationmightliveItisaltogetherfangandproperthatweshoulddothisButinalargersensewecannotdedicatewecannotconsecratewecannothallowthisgroundThebravelmenlivinganddeadwhostruggledherehaveconsecrateditfaraboveourpoorponwertoaddordetractTgheworldadswfilllittlenotlenorlongrememberwhatwesayherebutitcanneverforgetwhattheydidhereItisforusthelivingrathertobededicatedheretotheulnfinishedworkwhichtheywhofoughtherehavethusfarsonoblyadvancedItisratherforustobeherededicatedtothegreattdafskremainingbeforeusthatfromthesehonoreddeadwetakeincreaseddevotiontothatcauseforwhichtheygavethelastpfullmeasureofdevotionthatweherehighlyresolvethatthesedeadshallnothavediedinvainthatthisnationunsderGodshallhaveanewbirthoffreedomandthatgovernmentofthepeoplebythepeopleforthepeopleshallnotperishfromtheearth";

    string reverseStr = MoonString::Reverse(INPUT_TEXT);

    string maxSubStr1 = GetMaxReverseSubString(INPUT_TEXT, reverseStr);
    string maxSubStr2 = GetMaxReverseSubString(reverseStr, INPUT_TEXT);

    string maxSubStr = maxSubStr1.length() > maxSubStr2.length() ? maxSubStr1 : maxSubStr2;

    cout << "最长子串为:" << endl
            << maxSubStr << endl
            << "长度为:" << maxSubStr.length() << endl;

    /*********************************算法结束*******************************/

    QueryPerformanceCounter(&timeEnd);
    cout << "Total Milliseconds is " << (double)(timeEnd.QuadPart - timeStart.QuadPart) * 1000 / freq.QuadPart << endl;

    time_t currentTime = time(NULL);
    const char BEEP_CHAR = '\007';

    const int MAX_TIME_CHAR = 30;
    char timeStr[MAX_TIME_CHAR];

    ctime_s(timeStr, MAX_TIME_CHAR, ¤tTime);
    cout << endl << "By GodMoon" << endl << timeStr << BEEP_CHAR;

    system("pause");
}

//主函数
int main()
{
    F1();
    return 0;
}

/*
void F1()
最长子串为:
ranynar
长度为:7
Total Milliseconds is 182.737

By GodMoon
Fri Mar 08 21:41:24 2013
*/


第二题,分为几部分,第一部车是找出大于227000的最小素数同时也是Fibonacci数X,将其加1得Y,求Y的所有唯一质因数之和。

#pragma once

#include <windows.h>

class MoonMath
{
public:
    MoonMath(void);
    ~MoonMath(void);

    //************************************
    // Method:    IsInt
    // Access:    public 
    // Describe:  判断double值在epsilon的范围内是否很接近整数
    //            如1.00005在epsilon为0.00005以上就很接近整数
    // Parameter: double doubleValue    要判断的double值
    // Parameter: double epsilon        判断的精度,0 < epsilon < 0.5
    // Parameter: INT32 & intValue      如果接近,返回最接近的整数值
    // Returns:   bool                  接近返回true,否则返回false
    //************************************
    static bool IsInt(double doubleValue,double epsilon,INT32 &intValue);

    //************************************
    // Method:    Sign
    // Access:    public 
    // Describe:  获取value的符号
    // Parameter: T value   要获取符号的值
    // Returns:   INT32     正数、0和负数分别返回1、0和-1
    //************************************
    template <typename T>
    static INT32 Sign(T value);

    //************************************
    // Method:    IsPrimer
    // Access:    public 
    // Describe:  判断一个数是否是素数
    // Parameter: UINT32 num    要判断的数
    // Returns:   bool          是素数返回true,否则返回false
    //************************************
    static bool IsPrimer(UINT32 num);
};


#include "MoonMath.h"
#include <cmath>

MoonMath::MoonMath(void)
{
}


MoonMath::~MoonMath(void)
{
}

template <typename T>
INT32 MoonMath::Sign(T value)
{
    if (value > 0)
    {
        return 1;
    }
    else if (value == 0)
    {
        return 0;
    }
    else
    {
        return -1;
    }
}

bool MoonMath::IsInt(double doubleValue, double epsilon, INT32 &intValue)
{
    if (epsilon > 0.5 || epsilon < 0)
    {
        return false;
    }
    
    if(INT32(doubleValue + epsilon) == INT32(doubleValue - epsilon))
    {
        return false;
    }

    INT32 value = INT32(doubleValue);

    intValue = (fabs(doubleValue - value) > 0.5) ? (value + MoonMath::Sign(doubleValue)) : (value) ;
    return true;
}

bool MoonMath::IsPrimer(UINT32 num)
{
    // 0和1不是素数
    if(num <= 1)
    {
        return false;
    }

    UINT32 sqrtOfNum = sqrt((double)num); // num的2次方

    // 从2到sqrt(num),如果任何数都不能被num整除,num是素数,否则不是
    for(UINT32 i = 2; i <= sqrtOfNum; ++i)
    {
        if(num % i == 0)
        {
            return false;
        }
    }

    return true;
}


/*
The Cue Programming Challenge

Level 2

----------------------------------------

Congratulations.  You have reached level 2.

To get the password for level 3, write code to find the first prime
fibonacci number larger than a given minimum.  For example, the first
prime fibonacci number larger than 10 is 13.

When you are ready, go here or call this automated
number (415) 799-9454.

You will receive additional instructions at that time.  For the second portion
of this task, note that for the number 12 we consider the sum of the prime divisors
to be 2 + 3 = 5.  We do not include 2 twice even though it divides 12 twice.

Enter the password to access level 3:
*/

/*
上面的go here:

Step 1. Use your code to compute the smallest prime fibonacci number
greater than 227,000.  Call this number X.

Step 2. The password for level 3 is the sum of prime divisors of X + 1.

Note: If you call the number instead, it will check your answer for step 1.
*/


#include <iostream>
#include <windows.h>
#include <ctime>

#include <set>
#include "MoonMath.h"

using namespace std;

//************************************
// Method:    GetNextFibonacciNum
// Access:    public
// Describe:  获取Fibonacci数列,每次获取都是获取到下一个,因此是一次性函数
// Returns:   UINT32
//************************************
UINT32 GetNextFibonacciNum()
{
    static UINT32 lastNum = 0;
    static UINT32 currNum = 1;

    currNum += lastNum;
    lastNum = currNum - lastNum;

    return lastNum;
}

UINT32 GetX(UINT32 startNum)
{
    UINT32 X;

    while((X = GetNextFibonacciNum()) <= startNum);

    while(!MoonMath::IsPrimer(X))
    {
        X = GetNextFibonacciNum();
    }

    return X;
}

void GetPrimerDivisors(UINT32 num, set<UINT32> &divisors)
{
    UINT32 sqrtOfY = sqrt((double)num);

    for(UINT32 i = 2; i <= sqrtOfY; ++i)
    {
        if(!MoonMath::IsPrimer(i))
        {
            continue;
        }

        if(num % i == 0)
        {
            divisors.insert(i);
            num /= i;
            sqrtOfY = sqrt((double)num);
        }
    }

    if(MoonMath::IsPrimer(num))
    {
        divisors.insert(num);
    }
}

//************************************
// Method:    CalcSum
// Access:    public
// Describe:  计算set容器内数据的和
// Parameter: set<T> contain
// Returns:   T
//************************************
template <typename T>
T CalcSum(set<T> contain)
{
    T sum = 0;

    for(set<T>::iterator it = contain.begin(); it != contain.end(); ++it)
    {
        sum += *it;
    }

    return sum;
}

void F1()
{
    cout << "void F1()" << endl;

    LARGE_INTEGER timeStart, timeEnd, freq;
    QueryPerformanceFrequency(&freq);
    QueryPerformanceCounter(&timeStart);

    /*********************************算法开始*******************************/

    UINT32 START_NUM = 227000;

    UINT32 X = GetX(START_NUM);

    cout << "大于" << START_NUM << "的最小的Fibonacci质数X是:" << X << endl;

    UINT32 Y = X + 1;

    cout << "Y = X + 1 = " << Y << endl;

    // 获得Y的所有不同的质因数
    set<UINT32> divisors;
    GetPrimerDivisors(Y, divisors);

    // 求和
    UINT32 sum = CalcSum(divisors);

    // 输出
    cout << "Y的所有质因数之和为:";
    for(set<UINT32>::iterator it = divisors.begin(); it != divisors.end(); it++)
    {
        cout << *it << " + ";
    }

    cout << "\b\b= " << sum << endl;


    /*********************************算法结束*******************************/

    QueryPerformanceCounter(&timeEnd);
    cout << "Total Milliseconds is " << (double)(timeEnd.QuadPart - timeStart.QuadPart) * 1000 / freq.QuadPart << endl;

    time_t currentTime = time(NULL);
    const char BEEP_CHAR = '\007';

    const int MAX_TIME_CHAR = 30;
    char timeStr[MAX_TIME_CHAR];

    ctime_s(timeStr, MAX_TIME_CHAR, ¤tTime);
    cout << endl << "By GodMoon" << endl << timeStr << BEEP_CHAR;

    system("pause");
}

//主函数
int main()
{
    F1();
    return 0;
}

/*
void F1()
大于227000的最小的Fibonacci质数X是:514229
Y = X + 1 = 514230
Y的所有质因数之和为:2 + 3 + 5 + 61 + 281 = 352
Total Milliseconds is 10.7617

By GodMoon
Fri Mar 08 23:23:02 2013
*/


第三题,给一串数字,从中找出一组字串,字串中最大的数字是其他数字之和,求字串的数目。

/*
The Cue Programming Challenge

Level 3

----------------------------------------

Congratulations.  You have reached the final level.

For the final task, you must find all subsets of an array
where the largest number is the sum of the remaining numbers.
For example, for an input of:

(1, 2, 3, 4, 6)

the subsets would be

1 + 2 = 3
1 + 3 = 4
2 + 4 = 6
1 + 2 + 3 = 6

Here is the list of numbers you should run your code on: 3, 4, 9, 14, 15, 19, 28, 37, 47, 50, 54, 56, 59, 61, 70, 73, 78, 81, 92, 95, 97, 99
The password is the number of subsets.  In the above case the
answer would be 4.

Enter the password to complete the challenge:

给一串数字,从中找出一组字串,字串中最大的数字是其他数字之和,求字串的数目。
英文真啰嗦。
*/

#include <iostream>
#include <windows.h>
#include <ctime>
#include <algorithm>
#include <functional>

using namespace std;

template <typename T>
bool CheckSubset(UINT32 bitMap, const T array[], UINT32 arraySize)
{
    if(bitMap == 0)
    {
        return false;
    }

    UINT32 index = arraySize - 1;
    T maxNum = 0;
    T currSum = 0;

    // 寻找最大数
    while((bitMap & 1) != 1)
    {
        --index;
        bitMap >>= 1;
    }

    maxNum = array[index];

    do
    {
        bitMap >>= 1;
        --index;

        if((bitMap & 1) == 1)
        {
            currSum += array[index];
        }
    }
    while(bitMap != 0);

    return currSum == maxNum;
}

// 求数组长度
#define SizeofArray(array) ((sizeof(array))/(sizeof(array[0])))

void F1()
{
    cout << "void F1()" << endl;

    LARGE_INTEGER timeStart, timeEnd, freq;
    QueryPerformanceFrequency(&freq);
    QueryPerformanceCounter(&timeStart);

    /*********************************算法开始*******************************/
    const UINT32 BITS_PER_BYTE = 8;
    const UINT32 MAX_SUPPORT_LENGTH = sizeof(UINT32) * BITS_PER_BYTE;
    const INT32 NUM_ARRAY[] = {3, 4, 9, 14, 15, 19, 28, 37, 47, 50, 54, 56, 59,
                               61, 70, 73, 78, 81, 92, 95, 97, 99};

    UINT32 num = SizeofArray(NUM_ARRAY);

    if(num > MAX_SUPPORT_LENGTH)
    {
        cout << "Error: 数组元素太多,无法计算!仅支持最多" << MAX_SUPPORT_LENGTH << "个元素" << endl;
        return;
    }

    // 排序
    INT32 *pNumArraySorted = new INT32[num];

    (void)memcpy(pNumArraySorted, NUM_ARRAY, num * sizeof(*pNumArraySorted));

    sort(pNumArraySorted, pNumArraySorted + num - 1, less<INT32>());

    // 遍历所有子串
    UINT32 bitMap;
    UINT32 maxBitMap = 1 << (num + 1);
    UINT32 subsetsNum = 0;

    for(bitMap = 1; bitMap < maxBitMap; ++bitMap)
    {
        if(CheckSubset(bitMap, pNumArraySorted, num))
        {
            ++subsetsNum;
        }
    }

    delete[] pNumArraySorted;

    cout << "共有子串" << subsetsNum << "个" << endl;

    /*********************************算法结束*******************************/

    QueryPerformanceCounter(&timeEnd);
    cout << "Total Milliseconds is " << (double)(timeEnd.QuadPart - timeStart.QuadPart) * 1000 / freq.QuadPart << endl;

    time_t currentTime = time(NULL);
    const char BEEP_CHAR = '\007';  // 计算完毕叫一声

    const int MAX_TIME_CHAR = 30;
    char timeStr[MAX_TIME_CHAR];

    ctime_s(timeStr, MAX_TIME_CHAR, ¤tTime);
    cout << endl << "By GodMoon" << endl << timeStr << BEEP_CHAR;

    system("pause");
}

//主函数
int main()
{
    F1();
    return 0;
}

/*
void F1()
共有子串179个
Total Milliseconds is 1249.17

By GodMoon
Sat Mar 09 08:45:07 2013
*/

/*
The Cue Programming Challenge

The End

----------------------------------------

Congratulations.  You completed the challenge.  Your completion token is *******-***-***-***.

We'd love to talk to you - send your completion token, the code you wrote
during the challenge, and your resume to

jobs+i+solved+the+challenge@cueup.com

Even if you're not looking for a job, we'd love to hear what you thought
about the challenge.

For a new challenge, see if you can complete The Colossal Cue Adventure.


*/



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值