素数环(dfsamp;amp;STL做法)HDU - 1016
生活随笔
收集整理的這篇文章主要介紹了
素数环(dfsamp;amp;STL做法)HDU - 1016
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? ?HDU - 1016? cxsys訓練第一周&第二周
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.?
?
Inputn (0 < n < 20).?
OutputThe 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 8Sample Output Case 1: 1 4 3 2 5 6 1 6 5 2 3 4Case 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
????這題第一思路顯然dfs,但是最近想了一下可以用next_permutation做,結果TLE了,究其原因,就是深搜的時候剪枝做的比較好,所以運行的時間一對比(樣例是n=18),會發現dfs的解法程序在不停的輸出數據,但是STL的卻僅僅是在閃光標。
????得結論:有的題剪枝的十分優雅(比如這題,如果1 2 判斷不成立,那么第二個數放2這一大支直接剪掉了),便不能用next_permutation,有的題(比如李白打酒,一道藍橋杯水題),便可以這樣做(現在一想主要原因就是藍橋杯這個只需要結果,而不限制時間),還有啊比如讓你輸出全排列,你用dfs會很慢,而next_per就相對來說快一點,各有優勢吧,當不需要剪枝的時候,next_per感覺還是略占優勢,畢竟內部是用swap實現的而不是深搜,但是對于有大剪枝的題,還是慎用吧!因為next_per是對每一個全排列在判斷是否符合條件(即搜索樹上已經到葉了,相當于完全暴力完全無剪枝)
下面上next_per的代碼:(TLE)
#include<iostream> #include<algorithm> #include<cstring> using namespace std; int a[35]; int cnt; int su[70]; bool isPrime[55]={0,0,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};//寫到37 void init(int n) {for(int i = 1; i<=n; i++) {a[i]=i;} } bool ok(int n) {int i;for(i = 1; i<n; i++) {if(!isPrime[a[i]+a[i+1]]) return 0;}if(!isPrime[a[i]+a[1]]) return 0;return 1; } int main() {int n;int iCase=0; // prime();while(~scanf("%d",&n)) {iCase++;printf("Case %d:\n",iCase);if(n==1) {printf("1\n");}memset(a,0,sizeof(a));init(n);do{if(ok(n)) {int i;for( i = 1; i<n; i++) {printf("%d ",a[i]);}printf("%d\n",a[i]);}}while(next_permutation(a+2,a+n+1));printf("\n");}return 0 ; }下面是dfs的代碼:(用時608ms)
#include<iostream> #include<cstring> using namespace std; void dfs(int step); bool book[25]; int a[25]; int n; bool isPrime[38] = {0,0,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-37的打表 int main() {int cnt=1;while(scanf("%d",&n)!=EOF){memset(book,0,sizeof(book));memset(a,0,sizeof(a));a[1]=1; // 別忘這個!! printf("Case %d:\n",cnt);cnt++; dfs(2);printf("\n"); }return 0 ; } void dfs(int step){if(step==n+1&&isPrime[a[step-1]+1]){for(int i=1;i<=n;i++){printf("%d",a[i]);if(i<n){printf(" "); }else{printf("\n");}}return ;}for(int i=2;i<=n;i++){if(book[i]) continue;if(!isPrime[i+a[step-1]]) continue;book[i]=1;a[step]=i;dfs(step+1);book[i]=0;} }總結
以上是生活随笔為你收集整理的素数环(dfsamp;amp;STL做法)HDU - 1016的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浦发信用卡万用金怎么申请 六种方式任你选
- 下一篇: 全球股市开始下跌,大宗商品却大涨,意味着