【ProjectEuler】ProjectEuler_035

// Problem 35
// 17 January 2003
//
// The number, 197, is called a circular prime because all rotations of the digits: 197, 971, and 719, are themselves prime.
//
// There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, and 97.
//
// How many circular primes are there below one million?

#include <iostream>
#include <windows.h>
#include <cmath>
using namespace std;

// 判断某数是否为素数,此函数添加了一个1000000以内的静态数组记录素数
bool IsPrimeNum(int num)
{
    const int MAX_PRIME = 1000000;
    static char prime[MAX_PRIME] = {0};		//0:未记录。1:是素数。2:不是素数

    //防止数组越界
    if(num < 1 || num > MAX_PRIME)
    {
        return false;
    }

    if(prime[num] == 0)
    {
        if((num % 2 == 0 && num > 2) || num <= 1)
        {
            prime[num] = 2;
            return false;
        }

        int sqrtNum = (int)sqrt((double)num);

        for(int i = 3; i <= sqrtNum; i += 2)
        {
            if(num % i == 0)
            {
                prime[num] = 2;
                return false;
            }
        }

        prime[num] = 1;
        return true;
    }
    else if(prime[num] == 1)
    {
        return true;
    }
    else if(prime[num] == 2)
    {
        return false;
    }

    return false;
}

// 获取某数的位数
int GetDigitCount(int num)
{
    int count = 0;

    while(num != 0)
    {
        count++;
        num /= 10;
    }

    return count;
}

// 获取某个数字的旋转数,如1952->9521,digitNum为它的位数,因为如果带0的话,是不行的
// 其实后来看了别人的解答,只有1,3,5,7,9组成的数有这种条件(排除2),所以可以进一步缩小范围
int RotationNum(int num, int digitNum)
{
    int place = 10;	//位数,从十位开始
    int result = 0;	//结果

    for(int i = 1; i < digitNum; i++)		//从1开始,所以留下了最高位
    {
        result += num % 10 * place;
        place *= 10;
        num /= 10;
    }

    result += num;	//取最高位作为个位
    return result;
}

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

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

    const int MAX_NUM = 1000000;

    int currentNum = 0;			//当前处理的数
    bool skip = false;			//如果失败,置为true,表示不符合要求
    int circularPrimeCount = 0;	//循环素数个数
    int digitCount = 0;

    for(int i = 2; i < MAX_NUM; i++)
    {
        currentNum = i;
        skip = false;
        digitCount = GetDigitCount(i);		//获取此数的位数

        do
        {
            if(!IsPrimeNum(currentNum))		//不是素数
            {
                skip = true;
                break;
            }

            currentNum = RotationNum(currentNum, digitCount);
        }
        while(currentNum != i);

        if(!skip)		//是素数
        {
            cout << i << endl;
            circularPrimeCount++;
        }
    }

    cout << MAX_NUM << "以内循环素数的个数为" << circularPrimeCount << endl;

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

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

/*
void F1()
2
3
5
7
11
13
17
31
37
71
73
79
97
113
131
197
199
311
337
373
719
733
919
971
991
1193
1931
3119
3779
7793
7937
9311
9377
11939
19391
19937
37199
39119
71993
91193
93719
93911
99371
193939
199933
319993
331999
391939
393919
919393
933199
939193
939391
993319
999331
1000000以内循环素数的个数为55
Total Milliseconds is 853.053

By GodMoon
2011年11月5日0:09:28
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值