题目链接:http://acm.zju.edu.cn /show_problem.php?pid=1457
寒啊……居然差不多把错误都犯遍了,OLE->RTE->TLE->WA->PE->AC,做了好久,而且还是传说中的简 单题,这个题目就是简单的回溯,剪枝也相当简单,那我怎么就……
题目的意思也比较好理解,就是要求把一个序列排成一个环(又是序列,呵呵),当然这个序列是从1,2,3,4,5,....,n,要求这个序列的性质是相 邻两个数的和是一个素数。要求输出满足这个性质环的全部组合。开始的时候也不知道怎么了居然出现OLE,寒啊。。。出现TLE的原因是没有处理奇数和偶 数,实际上,如果给出的n是奇数就可以不做回溯了,因为这个时候奇数的个数比偶数多一个,不论怎么排列,至少有一对相邻的数都是奇数,这两个数的和不可能 是素数了,这样就可以大大加快速度了。不过我的程序的0.78s与前面的0.23s比起来还是慢啊
题目的思路比较直接,就是回溯,给出各种情况,当出现相邻两个数的和不是素数的时候剪掉。
不管怎样,代码如下:in C++
代码
1
#include
<
iostream
>
2 #include < cstdio >
3 using namespace std;
4
5 int isprime[ 40 ] ;
6 int p[ 21 ] ;
7 int visited[ 21 ] ;
8
9 void perm( int k , int n)
10 {
11 for ( int i = 2 ; i <= n ; i ++ )
12 {
13 if ( ! visited[i] && isprime[p[k - 1 ] + i])
14 {
15 visited[i] = 1 ;
16 p[k] = i ;
17 perm(k + 1 , n) ;
18 visited[i] = 0 ;
19 }
20 }
21 if (k == n + 1 && isprime[p[k - 1 ] + 1 ])
22 {
23 for ( int i = 1 ; i <= n ; i ++ )
24 {
25 if (i != 1 )
26 printf( " " );
27 printf( " %d " ,p[i]);
28 }
29 printf( " \n " );
30 return ;
31 }
32 }
33 int main()
34 {
35 int cases = 0 ;
36 int n ;
37
38 memset(isprime, 0 , 40 );
39 isprime[ 2 ] = isprime[ 3 ] = isprime[ 5 ] = isprime[ 7 ] = isprime[ 11 ] = isprime[ 13 ] = isprime[ 17 ] = isprime[ 19 ]
40 = isprime[ 23 ] = isprime[ 29 ] = isprime[ 31 ] = isprime[ 37 ] = 1 ;
41 while (scanf( " %d " , & n) != EOF)
42 {
43 printf( " Case %d:\n " , ++ cases);
44 if (n % 2 == 0 )
45 {
46 memset(visited , 0 , n + 1 ) ;
47 p[ 1 ] = 1 ;
48 perm( 2 , n) ;
49
50 }
51 printf( " \n " );
52 }
53
54 return 0 ;
55 }
56
2 #include < cstdio >
3 using namespace std;
4
5 int isprime[ 40 ] ;
6 int p[ 21 ] ;
7 int visited[ 21 ] ;
8
9 void perm( int k , int n)
10 {
11 for ( int i = 2 ; i <= n ; i ++ )
12 {
13 if ( ! visited[i] && isprime[p[k - 1 ] + i])
14 {
15 visited[i] = 1 ;
16 p[k] = i ;
17 perm(k + 1 , n) ;
18 visited[i] = 0 ;
19 }
20 }
21 if (k == n + 1 && isprime[p[k - 1 ] + 1 ])
22 {
23 for ( int i = 1 ; i <= n ; i ++ )
24 {
25 if (i != 1 )
26 printf( " " );
27 printf( " %d " ,p[i]);
28 }
29 printf( " \n " );
30 return ;
31 }
32 }
33 int main()
34 {
35 int cases = 0 ;
36 int n ;
37
38 memset(isprime, 0 , 40 );
39 isprime[ 2 ] = isprime[ 3 ] = isprime[ 5 ] = isprime[ 7 ] = isprime[ 11 ] = isprime[ 13 ] = isprime[ 17 ] = isprime[ 19 ]
40 = isprime[ 23 ] = isprime[ 29 ] = isprime[ 31 ] = isprime[ 37 ] = 1 ;
41 while (scanf( " %d " , & n) != EOF)
42 {
43 printf( " Case %d:\n " , ++ cases);
44 if (n % 2 == 0 )
45 {
46 memset(visited , 0 , n + 1 ) ;
47 p[ 1 ] = 1 ;
48 perm( 2 , n) ;
49
50 }
51 printf( " \n " );
52 }
53
54 return 0 ;
55 }
56