ZOJ 1457 题解

    题目链接: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++


ExpandedBlockStart.gif 代码
 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 


转载于:https://www.cnblogs.com/vivyli/archive/2010/02/05/1664067.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值