素数环
时间限制: 5 Sec 内存限制: 128 MB
提交: 224 解决: 102
[提交][状态][我的提交]
题目描述
输入正整数n,把整数1,2,3,…,n组成一个环,使得相邻两个整数之和均为素数。小强同学看过这个题,笑了:呵呵,打表!
Mr. Wu为了阻止小强打表,决定这样:
把全部的解按字典序排序后,从1开始编号,依次输出指定编号的k组解。最后一行输出总的方案数。同一个素数环只算一次。
输入
第1行:2个整数,n(n<=18)和k(1<=k<=10)
第2行:共有k个从小到大排列的整数,表示要输出的解的编号。
输出
前k行,每行一组解,对应于一个输入
第k+1行:一个整数,表示总的方案数。
样例输入
Copy (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)
10 4
1 2 5 8
样例输出
1 2 3 4 7 6 5 8 9 10
1 2 3 4 7 10 9 8 5 6
1 2 3 8 5 6 7 10 9 4
1 2 3 10 9 8 5 6 7 4
96
提示
输入样例说明:
对1,2,…,10组成素数环。要输出字典序的第1,2,5,8等4组解
输出样例说明:
第1,2,5,8组解分别是样例中所列的4行。总共有96组解。
[提交][状态][讨论版]
进步的天梯:
1~‘同一个素数环只算一次。’,同学们看到这个提示,一定要注意:我们面对的字符是连在一起的(注意),所以,我们在看到这样的提示,一定要固定一个数为开头(就像火车有火车头),只有这样,我们才好计算。
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int n,num,k;
int j=1;
int a[15],sum=1;
bool z[25];
int su[25];
bool pd(int m) //判断素数
{
for(int i=2;i<=sqrt(m);i++) //注意要开方(死结构)
if(m%i==0) return 0;
return 1;
}
void print() //输出
{
for(int i=1;i<n;i++)
printf("%d ",su[i]);
printf("%d\n",su[n]);
}
int search(int x)
{
for(int i=2;i<=n;i++)//已定开头
{
if((z[i]==0)&&pd(i+su[x-1]))
{
z[i]=1;
su[x]=i;
if(x==n)
{
if(pd(su[n]+su[1]))
{
num++;
if(num==a[sum])
{
sum++;print();
}
}
}
else search(x+1);
z[i]=0;
}
}
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++)
scanf("%d",&a[i]);
su[1]=1; //定义1为开头
z[1]=1;
search(2);
printf("%d",num);
}
/**************************************************************
Problem: 2266
User: ybxq005
Language: C++
Result: 正确
Time:3993 ms
Memory:1044 kb
****************************************************************/
相关阅读
问题 A: 素数环问题 时间限制: 1 Sec 内存限制: 256 MB 题目描述 素数环是一个计算机程序问题,指的是将从1到n这n个整数围成
时限:1000ms 内存限制:10000K 总时限:3000ms 描述: 把1到20这重新排列,使得排列后的序列A满足:a. 任意相邻两个数之和是素数b. 不存在
素数环NOJ1104回溯法应用,显然解空间是一个排列集,n最大为16,最大解空间为16!= 2*10^13(阶乘)。用next_permutation生成每排列,然后判断