最近搜索都不会写了(我太菜了),写几个紫书例题。
题意:输入正整数n,把1-n组成一个环,使得相邻两个数之和均为素数。n<=16。多组数据。
样例输入
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 6 2 8
样例输出
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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
输入很坑,1、从第二组数据开始,Case前面有换行。
2、每行最后无空格。
下面是代码
#include<iostream> #include<cstdio> #include<string> #include<algorithm> #include<cstring> using namespace std; int is_prime[100],prime[100]; void euler(){//欧拉筛 memset(is_prime,1,sizeof(is_prime)); is_prime[0] = is_prime[1] = 0; for(int i = 2; i <= 100; i++){ if(is_prime[i]) prime[++prime[0]] = i; for(int j = 1; j <= 100 && i*prime[j] <= 100; j++){ is_prime[i*prime[j]] = 0; if(i%prime[j] == 0) break; } } } int t,n,a[18],vis[18]; void dfs(int cur){ if(cur == n&&is_prime[a[0] + a[cur - 1]]){//判断首尾之和是否是质数 printf("%d",a[0]); for(int i = 1; i < cur; i++) printf(" %d",a[i]); printf("\n"); return; } for(int i = 2; i <= n; i++){//枚举第二个到最后一个元素 if(!vis[i]&&is_prime[i + a[cur - 1]]){ a[cur] = i; vis[i] = 1; dfs(cur + 1); vis[i] = 0; } } } int main(){ euler(); a[0] = vis[1] = 1;//环中第一个元素一定是1 while(cin >> n){ if(t)printf("\n"); cout << "Case " << ++t << ":" << endl; dfs(1);//由于第一个元素已经确定,所以cur从1开始 } return 0; }
根据我的感性理解,如果第一个元素不确定为1的话,枚举的是全排列,然而这个题找的不是排列,而是环。如果第一个元素不确定为1,会重复输出相同的情况。
如n=3时,1 2 3和2 3 1。
PS:提交Uva推荐vjudge