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

题目没什么好说的,我的方法中只求解了[0,3400)的素数,算得上是一个优化吧。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 const int N = 10000000;
 7 const int M = 8;
 8 const int P = 3400;
 9 bool mark[N];
10 bool used[M];
11 int divide[M];
12 int digit[M];
13 char str[M];
14 int len, ans;
15 bool flag[P];
16 int prime[P];
17 int cnt;
18 
19 void get()
20 {
21     memset( flag, 1, sizeof(flag) );
22     flag[0] = flag[1] = false;
23     cnt = 0;
24     for ( int i = 2; i < P; i++ )
25     {
26         if ( flag[i] )
27         {
28             prime[cnt++] = i;
29             for ( int j = i + i; j < P; j += i )
30             {
31                 flag[j] = false;
32             }
33         }
34     }
35 }
36 
37 bool isPrime( int a )
38 {
39     if ( a == 0 || a == 1 ) return false;
40     for ( int i = 0; i < cnt; i++ )
41     {
42         if ( prime[i] * prime[i] > a ) break;
43         if ( a % prime[i] == 0 ) return false;
44     }
45     return true;
46 }
47 
48 void judge( int depth )
49 {
50     int num = 0;
51     for ( int i = 0; i <= depth; i++ )
52     {
53         num = num * 10 + digit[i];
54     }
55     if ( isPrime(num) && !mark[num] )
56     {
57         ans++;
58         mark[num] = 1;
59     }
60 }
61 
62 void dfs( int depth )
63 {
64     if ( depth >= len ) return ;
65     for ( int i = 0; i < len; i++ )
66     {
67         if ( !used[i] )
68         {
69             digit[depth] = divide[i];
70             judge(depth);
71             used[i] = 1;
72             dfs( depth + 1 );
73             used[i] = 0;
74         }
75     }
76 }
77 
78 int main ()
79 {
80     get();
81     int t;
82     scanf("%d", &t);
83     while ( t-- )
84     {
85         scanf("%s", str);
86         len = strlen(str);
87         for ( int i = 0; i < len; i++ )
88         {
89             divide[i] = str[i] - '0';
90         }
91         ans = 0;
92         memset( used, 0, sizeof(used) );
93         memset( mark, 0, sizeof(mark) );
94         dfs(0);
95         printf("%d\n", ans);
96     }
97     return 0;
98 }

据说把1000W以内的素数表打出来都能过...

转载于:https://www.cnblogs.com/huoxiayu/p/4651562.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值