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以内的素数表打出来都能过...

你可能感兴趣的:(poj)