hdu 1016 dfs素數環,hdu1016dfs素數
背景:周賽e題,當時很快就有人出,我能看出來是dfs但是卻不能實現,哎以為自己能力不可寫出,結果低估自己了。
學習:1.打了一個素數表,比較快捷,還有素數判別方法的函數,只需要枚舉到該數的平方根即可,因為大於它的平方·根之後商都小於1,不可能再整除了。
int isPrime(int x){int i;for (i = 2; i <= sqrt(x*1.0); i++)//sqrt函數操作的是double。{if (x % i == 0) return 0;}return 1;}2.調了一個多小時盡然是又忘了回溯時下標也跟著減1!!!!!!!!
3.這裡在檢查一個數是否已經用過的時候,我用了每次都掃描已經用過的所有數的方法。其實可以建立一個數組visit[n],先memset(visit,1,sizeof(visit));沒用過一個數k,就把visit[k]=0;這樣就可以避免重複資料偵測了。
4.調試的時候出現了把函數名定義為關鍵字的低級錯誤。調試發現h,每調試一步就會自增1,這一定是邏輯錯誤,結果發現沒有回溯下標。
我代碼:
#include<stdio.h>int prime[12]={2,3,5,7,11,13,17,19,23,29,31,37};//素數表int n,str[21]={1},h;bool isprime(int a,int b);//輸入a[n]和a[n-1],如果看a[n]是否滿足和為素數且前面沒有出現過的要求。void makes(void); void makes(void) { if(h==n)//如果已經有n個元素了,考慮它是否和第一個元素對接,若對接則輸出。 { bool last=false; int zz=str[0]+str[n-1]; for(int i=0;i<12;i++) { if(zz==prime[i]) last=true; } if(last) { for(int ii=0;ii<n;ii++){if(ii) printf(" ");printf("%d",str[ii]);}printf("\n"); } } else{ for(int i=2;i<=n;++i ) { if(isprime(str[h-1],i)) { str[h]=i; h++; makes(); } } } h--; //注意注意注意!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! } bool isprime(int a,int b) { int z=a+b; for(int i=0;i<12;i++) { if(z==prime[i]) goto l1; } return false;l1: for(int k=0;k<h;k++) { if(str[k]==b) return false; } return true; }int main(void){int count=1;while(scanf("%d",&n)!=EOF&&n){h=1;printf("Case %d:\n",count);count++;makes();printf("\n");}return 0;}