您的位置:首页 > 其它

poj 3842 全排列+筛素数+暴力

2015-07-16 15:58 411 查看
题目没什么好说的,我的方法中只求解了[0,3400)的素数,算得上是一个优化吧。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int N = 10000000;
const int M = 8;
const int P = 3400;
bool mark
;
bool used[M];
int divide[M];
int digit[M];
char str[M];
int len, ans;
bool flag[P];
int prime[P];
int cnt;

void get()
{
memset( flag, 1, sizeof(flag) );
flag[0] = flag[1] = false;
cnt = 0;
for ( int i = 2; i < P; i++ )
{
if ( flag[i] )
{
prime[cnt++] = i;
for ( int j = i + i; j < P; j += i )
{
flag[j] = false;
}
}
}
}

bool isPrime( int a )
{
if ( a == 0 || a == 1 ) return false;
for ( int i = 0; i < cnt; i++ )
{
if ( prime[i] * prime[i] > a ) break;
if ( a % prime[i] == 0 ) return false;
}
return true;
}

void judge( int depth )
{
int num = 0;
for ( int i = 0; i <= depth; i++ )
{
num = num * 10 + digit[i];
}
if ( isPrime(num) && !mark[num] )
{
ans++;
mark[num] = 1;
}
}

void dfs( int depth )
{
if ( depth >= len ) return ;
for ( int i = 0; i < len; i++ )
{
if ( !used[i] )
{
digit[depth] = divide[i];
judge(depth);
used[i] = 1;
dfs( depth + 1 );
used[i] = 0;
}
}
}

int main ()
{
get();
int t;
scanf("%d", &t);
while ( t-- )
{
scanf("%s", str);
len = strlen(str);
for ( int i = 0; i < len; i++ )
{
divide[i] = str[i] - '0';
}
ans = 0;
memset( used, 0, sizeof(used) );
memset( mark, 0, sizeof(mark) );
dfs(0);
printf("%d\n", ans);
}
return 0;
}


据说把1000W以内的素数表打出来都能过...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: