当前位置:首页 > 题解目录 > 正文内容

质数环

亿万年的星光5年前 (2021-01-28)题解目录2065

【题目描述】

有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环。为了简便起见,我们规定每个素数环都从1开始。例如,下面就是6的一个素数环。
1 4 3 2 5 6
1 6 5 2 3 4

【输入描述】

有多组测试数据,每组输入一个n(0<n<20),n=0表示输入结束。

【输出描述】

每组第一行输出对应的Case序号,从1开始。如果存在满足题意叙述的素数环,从小到大输出。否则输出No Answer。

【样例输入】

6
8
3
0

【样例输出】

Case1:
1 4 3 2 5 6
1 6 5 2 3 4
Case2:
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
Case3:
No Answer

【题目分析】

(1)搜索回溯的题目。从1开始,每个位置有N种不同的可能,只要填进去的数合法就行。
(2)合法指的是与前面的数不同,与左边相邻的和是一个素数
(3)最后一个数还要与第一个判断。


【参考代码】

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int n,ans[100],flag[100]; //输入数,结果数组,标记数组
//判断两个数的和是不是素数函数
int prime(int x, int y)
{
   int k=2, i=x+y;
   while(k<=sqrt(i) && i%k!=0)
       k++;
   if(k>sqrt(i))
       return 1;
   else
       return 0;    
}
//打印输出函数
int print()
{
   for(int i=1;i<=n;i++)
       cout<<ans[i]<<" ";
   cout<<endl;    
}
//搜索回溯算法
int search(int k)
{
   int i;
   for(i=1;i<=n;i++) //n个数
       if( prime(ans[k-1],i) && (flag[i]==0)) //判断与前一个数是否构成素数及这个数当前是不是可用    
       {    ans[k]=i;
           flag[i]=1; //标记当前这个数使用过了
           if(k==n) //到达边界
           {
               if( prime(ans[n],ans[1])) //严重最后一个和第一个
                   print();
           }
           else
               search(k+1);
           flag[i]=0;
   }
}
int main()
{
   cin>>n;
   search(1); //从第一个位置开始找
   return 0;
}

但是你运行上面的代码后发现和结果不一样,因为题目要求每个序列必须从1开头。所以还要再改一下,我们稍微改下if判断条件就可以实现了。

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int n,ans[100],flag[100]; //输入数,结果数组,标记数组
//判断两个数的和是不是素数函数
int prime(int x, int y)
{
   int k=2, i=x+y;
   while(k<=sqrt(i) && i%k!=0)
       k++;
   if(k>sqrt(i))
       return 1;
   else
       return 0;    
}
//打印输出函数
int print()
{
   for(int i=1;i<=n;i++)
       cout<<ans[i]<<" ";
   cout<<endl;    
}
//搜索回溯算法
int search(int k)
{
   int i;
   for(i=1;i<=n;i++) //n个数
       if( prime(ans[k-1],i) && (flag[i]==0)) //判断与前一个数是否构成素数及这个数当前是不是可用    
       {    ans[k]=i;
           flag[i]=1; //标记当前这个数使用过了
           if(k==n) //到达边界
           {
               if( prime(ans[n],ans[1]) && ans[1]==1) //严重最后一个和第一个
                   print();
           }
           else
               search(k+1);
           flag[i]=0;
   }
}
int main()
{
   cin>>n;
   search(1); //从第一个位置开始找
   return 0;
}


扫描二维码推送至手机访问。

版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

分享给朋友:
返回列表

上一篇:字符全排列(2)

下一篇:数列

相关文章

【题解】取余(2019青岛市程序设计竞赛)

【问题描述】给你n个正整数a1,a2,..,an。求(a1*a2*..an)%10007的值。【输入】第一行,n,表示整数的个数。第二行,n个用空格隔开的正整数。【输出】一个整数,(a1*a2*..a...

【题解】开关灯(2)

1.开关灯(light.cpp)【题目描述】某实验室共有n盏灯,灯的编号为1~n,每盏灯的初始状态是关闭的。现在有m位学生,每位学生可以前去抽取一张带数字的卡片,其数字为Ai,然后依次将自己手中的数字...

【题解】剔除相关数

【题目描述】一个数与另一个数如果含有相同数字和个数的字符,则称两数相关。现有一堆乱七八糟的整数,里面可能充满了彼此相关的数,请你用一下手段,自动地将其剔除。【输入描述】每组数据前有一个N(<10...

【题解】数字的选择

【题目描述】有n个非负整数,请从这n个非负整数中,选出m个数,在不改变m个数的顺序的情况下,构成一个新数列,要求该数列的中相邻两个数的差值绝对值的和尽可能小。请问,这个最小的差值绝对值的和是多少?比如...

【题解】分糖果

【题目描述】小A在生日这天收到了哥哥送来的一盒糖果,这盒糖果共有M个,小A要把这盒糖果放到N个盘子中(允许有盘子不放),请问,有多少种不同的放法?请注意:数值相同,顺序不同,我们视为是相同的放法,比如...

【题解】王国比赛

【题解】王国比赛

【题目描述】智慧之王 Kri 统治着一座王国。 这天 Kri 决定举行一场比赛,来检验自己大臣的智慧。 比赛由 n道判断题组成,有 m位大臣参加。现在你已经知道了所有大臣的答题情况,但尚未拿到答...