USACO Training Section1.5 Prime Palindromes (2) 筛法更快

另,题目提示先求回文再判断是否为素数。如果反过来,其实也是可行的,不过需要注意素数的计算范围必须在10000000内,不过这样会超内存。可以用位操作来替代整数、bool、char数组来记录筛法过程。看下下面两个筛法例程:
char is_prime[_max_];
int bis_prime[(_max_+31)>>5];
void char_sifter()
{
	for(register int i=2; i<=sqrt(float(_max_)); ; i++){
		if( !is_prime[i] )
			continue ;
		for( register int cur=i<<1; cur<_max_; cur+=i )
			is_prime[cur]=0 ;
	}
}

void bit_sifter()
{
	for(register int i=2; i<=sqrt(float(_max_)); i++){
		if( !( ((bis_prime[i>>5]) >> (i & 0x1f)) &1 ) )
			continue ;
		for( register int cur=i<<1; cur<_max_; cur+=i )
			bis_prime[cur>>5] &= ~(1<<(cur&0x1f)) ;
	}
}


一般会认为用char的跑的比按位存储的快,但事实相反, bit_sifter比char_sifter快两倍以上。原因:32位体系结构下,char操作是需要事先转化为32位的,其效率不如直接的位操作(基本上对应到汇编指令)。

用bit_sifter来做筛法得到素数然后在得到回文之后判断,0.302秒。之前的程序,直接得到回文判断是否为素数,0.794秒。内存使用上,前者为4152KB,后者为2916KB,差别不大。

干脆直接使用筛法写了个先判断素数再判断回数的程序,测试一次通过,极限下0.389 secs, 4148 KB。且该程序中没有跳过偶数位的数值,若跳过,还可更快些。

/*
ID: blackco3
TASK: pprime
LANG: C++
*/
#include <fstream>
#include <memory.h>
#include <math.h>
using namespace std;

#define _max_ 10000000
int bis_prime[(_max_+31)>>5];
const int sifter_gate=sqrt(float(_max_));
void bit_sifter( ) {
	for(register int i=2; i<=sifter_gate; i++){
		if( !( ((bis_prime[i>>5]) >> (i & 0x1f)) &1 ) )
			continue ;
		for( register int cur=i<<1; cur<_max_; cur+=i )
			bis_prime[cur>>5] &= ~(1<<(cur&0x1f)) ;
	}
}

int main()
{	
	ifstream fin("pprime.in");
	int low, up ;
	fin >> low >> up;
	up = up>_max_ ? _max_ : up ;
	ofstream fout("pprime.out");
	memset( bis_prime, 0xff, sizeof(bis_prime) ); 
	bit_sifter();
	register int *p_prime=bis_prime+(low>>5);
	register int bit = low&0x1f, i;
	int digit[8], rank, tmp, found ;
	for( int cur=low; cur<=up; cur++){
		if( (*p_prime >> bit)&1 ){
			rank=0 , tmp=cur;
			while( tmp ) 
				digit[rank++] = tmp%10, tmp /= 10 ;
			for( found=1, i=0; i<(rank>>1); i++)
				if( digit[i]!=digit[rank-1-i] ){
					found=0;
					break ;
				}
			if( found )
				fout << cur << endl;
		}
		if( ++bit==32 )
			bit=0, p_prime++ ;
	}
	return 0;
}



你可能感兴趣的:(C++,c,C#,UP)