Problem 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.
Note: the number of first circle should always be 1.
![](https://i-blog.csdnimg.cn/blog_migrate/427b1dd2282412709d583cc17eda983e.gif)
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.
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这题必须mark一记啊啊啊!!!本来挺简单的思路,它就是那么拽!代码:# include <iostream> # include <cstring> using namespace std; int visited[30],buffer[30],m; bool prime (int a,int b)//没问题 { int c,i; c = a+b; for (i = 2;i*i<=c;i++) { if (c%i == 0) { return 0; } } return 1; }// void dfs(int step) { int i; if (step> m && prime(1,buffer[m-1]))//所以位置已排满且第一位与最后一位之和为素数 { for(i = 0;i<m-1;i++)// { cout<<buffer[i]<<" "; } cout<<buffer[m-1]<<endl;// } else { for (i = 2;i<=m;i++)//从开始搜索一直到m { buffer[step-1] = i; if(!visited[i] && prime(buffer[step-2],buffer[step-1]))//当前位与前一位和为素数且没有被访问过 { visited[i] = 1;//标记为已搜索 dfs(step+1);//开始为下一个序列位置搜索 visited[i] = 0;//回溯要恢复前一步的状态 } } } } int main () { int cnt = 0; int i; while (cin>>m && m) { cnt++; memset(visited,0,sizeof(visited));//或者memset(visited,0,sizeof(visited)); visited[1] = 1;//表示已经使用 buffer[0] = 1; cout<<"Case "<<cnt<<":"<<endl; dfs(2); cout<<endl; } return 0; }这是AC了的,上次因为cin比scanf慢导致不能ac,从此就用scanf了,于是我原来在while里面写的是while(scanf("%d",n) && n)拿以前ac过的题目比较思路差不多啊,就是超时!!崩溃!
最后只要写成while(~scanf("%d",n) && n)就好了
上面两者的区别在于:前者是当输入n为0的时候结束程序
后者是当没有输入的时候结束程序
对于大多数函数来说都有一个返回值cin的返回值是成功输入的个数, 没有输入就返回0,于是while里面的表达式是0., 就结束
但是scanf呢也是成功输入的个数,但是没有输入不是返回0,而是返回-1
好吧,涨姿势了
下面还有一个方法,效率高,打表方法,因为输入的个数最大是20,只要打表到40的素数表就行了。
代码
#include<cstring> #include<iostream> //#include<algorithm> #include<cstdio> #include<cmath> int a[22]; int visit[22]; int prime[41]={0,1,1,1,0,1,0,1,0,0,0, 1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0,0,0}; int n; using namespace std; void dfs( int num)//长度,当前是第几个 { int i; if(num > n && prime[a[1]+a[n]])//长度满足且首尾和为素数 { for (i = 1; i < n; i++) { cout << a[i] << " "; } cout << a[n] << endl; } for (i = 2; i <= n; i++)//遍历 { a[num] = i; if(prime[a[num-1]+i] && !visit[i]) { visit[i] = 1; dfs(num+1); visit[i] = 0; } } } int main() { int cnt = 0; while (cin >> n && n ) { cnt++; memset(visit,0,sizeof(visit)); memset(a,0,sizeof(a)); a[1] = 1; visit[1] = 1; cout <<"Case "<< cnt << ":" << endl; dfs(2); cout << endl; } return 0; }
碎碎念:数据不大的情况下多想想打表。。。。