NYOJ-488 素数环

素数环

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 2
描述

有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环。

为了简便起见,我们规定每个素数环都从1开始。例如,下图就是6的一个素数环。

输入
有多组测试数据,每组输入一个n(0<n<20),n=0表示输入结束。
输出
每组第一行输出对应的Case序号,从1开始。
如果存在满足题意叙述的素数环,从小到大输出。
否则输出No Answer。
样例输入
6
8
3
0
样例输出
Case 1:
1 4 3 2 5 6
1 6 5 2 3 4
Case 2:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2
Case 3:
No Answer


                

01. #include<stdio.h>
02. #include<string.h>
03. int used[25]; //标记位。0:未被使用;1:已被使用;
04. int a[25]; //用于存储每一位上的数字;
05. int prime[45] = {0,0,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,
06. 1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,
07. 0,0,0,1,0,0,0
08. }; //素数的哈希表,下标代表具体数字,0:该数字不是素数;1:该数字是素数;
09.  
10. int n;
11. int count = 1;
12. //--------------------------------------------------------------
13. // 此函数用于判断填入第t位置的数字i是否满足题目要求;
14. //--------------------------------------------------------------
15.  
16. int check(int t,int i)//T里放I;t:第t个格子;i:要放入t中的数字;
17. {
18. if(t != n) //n:该素数环一共有n个数字;此举表示当t没到n的时候;
19. {
20. if(prime[i + a[t - 1]] == 1) //判断如果要填进去的数字i与前一个数字的和是素数
21. return 1; //满足上述条件,则返回1;
22. else
23. return 0; //不满足上述条件,则返回0;
24. }
25. else //如果当t已经等于n时,即表示已经填到最后一位的时候
26. {
27. if(prime[i + a[t - 1]] == 1 && prime[i + 1] == 1)/*如果要填进去的数字和前一位数字
28. 的和是素数,并且由于这是一个环,还要保证填进去的最后一个数字与第一个格子的数字‘1’的和是素数*/
29. return 1; //满足条件,返回1;
30. else
31. return 0; //不满足条件返回0;
32. }
33. }
34.  
35. void trackback(int t)
36. {
37. int i;
38. if(t > n) //当t大于n的时候,表明已经填完所有数字;
39. {
40. for(i = 1; i < n; i ++) //输出各个位上的数字;
41. printf("%d ",a[i]);
42. printf("%d\n",a[i]); //最后一位输出换行;
43. }
44. else //否则的话,表示尚未到最后一位数字;
45. {
46. for(i = 2; i <= n; i ++) //由于第一位i经固定是1,因此从第二位开始判断,到n;
47. {
48. if(!used[i] && check(t, i)) //如果填入的数字尚未被使用过,并且填在这个位置是经过check函数判断合理的;
49. {
50. used[i] = 1; //将这个数字标记位设为1,表示已被使用;
51. a[t] = i; //将这个数填入数组
52. trackback(t + 1);//进行下一步的判断,递归判断;
53. used[i] = 0;
54. }
55. }
56. }
57. }
58. int main()
59. {
60. n = 10;
61. while(scanf("%d",&n) != EOF)
62. {
63. if(n != 0)
64. {
65. if(n % 2 != 0 && n != 1)
66. {
67. printf("Case %d:\n",count);
68. count ++;
69. printf("No Answer\n");
70. continue;
71. }
72. memset(used, 0, sizeof(used));
73. a[1] = 1;
74. printf("Case %d:\n",count);
75. count ++;
76. trackback(2); //题目要求第一位是1,因此从第二位开始执行;
77. }}
78. return 0;
79. }


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值