Description
A ring is compose of n circles as shown in diagram. Put natural number 1, 2, …, n into each circle separately, and the sum of numbers in two adjacent circles should be a prime.
Note: the number of first circle should always be 1.
Input
n (0 < n < 20).
Output
The output format is shown as sample below. Each row represents a series of circle numbers in the ring beginning from 1 clockwisely and anticlockwisely. The order of numbers must satisfy the above requirements. Print solutions in lexicographical order.
You are to write a program that completes above process.
Print a blank line after each case.
Sample Input
6
8
Sample Output
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
题意:给你数字n( 0 < n < 20),然后全排列,要求输出的是相邻的两个数和是素数,坑点,第一个和最后一个相加也是素数, 而且第一个数必须是1。然后按照样例那样输出。
以前做过这个题,但是。。又超时了,原因第一个数是1,所以,不用广搜那么多次,所以,优化是必然的。先看一下Time Limit Exceeded的代码
#include <stdio.h>
#include <string.h>
int vis[1000], xx[1000];
int isprime(int x)
{
if(x <= 1) return 0;
else
{
for(int i = 2; i < x; i++)
{
if(!(x % i)) return 0;
}
return 1;
}
}
void dfs(int deep, int x)
{
if(deep == x)
{
if(xx[0] == 1 && isprime(xx[0] + xx[x - 1]))
{
int ant = 0;
for(int i = 1; i < x; i++) // 找符合题意的情况
{
if(isprime(xx[i] + xx[i - 1])) ant++;
}
if(ant == x - 1)
{
for(int i = 0; i < x; i++) //符合的情况输出
printf(i ? " %d" : "%d", xx[i]);
puts("");
return ;
}
}
}
for(int i = 1; i <= x; i++)
{
if(!vis[i])
{
vis[i] = 1; //直接先把所有的情况存起来
xx[deep] = i;
dfs(deep + 1, x);
vis[i] = 0;
}
}
}
int main()
{
int n;
int k = 1;
while(~scanf("%d", &n))
{
printf("Case %d:\n", k++);
memset(vis, 0, sizeof(vis));
dfs(0, n); //注意
puts("");
}
return 0;
}
超时的原因是n < 20, 20层for循环肯定爆,所以再看一下优化后的代码
#include <stdio.h>
#include <string.h>
int vis[100], xx[100], n;
int is(int x)
{
if(x <= 1) return 0;
else
{
for(int i = 2; i < x; i++)
{
if(x % i == 0) return 0;
}
return 1;
}
}
void dfs(int deep)
{
int ant = 0;
xx[0] = 1;
if(deep == n)
{
if(is(xx[0] + xx[n - 1]))
{
for(int i = 0; i < n; i++)
printf(i ? " %d" : "%d", xx[i]);
puts("");
}
}
for(int i = 2; i <= n; i++)
{
if(!vis[i])
{
xx[deep] = i;
if(is(xx[deep] + xx[deep - 1])) // 直接找符合题意的,把1略掉
{
vis[i] = 1;
dfs(deep + 1);
vis[i] = 0;
}
}
}
}
int main()
{
int k = 1;
while(~scanf("%d", &n))
{
printf("Case %d:\n", k++);
memset(vis, 0, sizeof(vis));
dfs(1); //注意
puts("");
}
return 0;
}
比较一下就知道有什么不同了吧。