回溯法和生成測試法比較
阿新 • • 發佈:2018-11-17
回溯法就是是把問題劃分為若干個步驟然後遞迴求解,如果本層沒有合適的解,將返回上一層,這個過程中剪了很多不必要的資料,所以效率較高。
生成測試時將所有的都窮舉出來,然後測試。
問題:素數環 https://vjudge.net/problem/UVA-524
回溯法:對應n=16,不輸出情況下使用43ms
#include<cstdio> #include<algorithm> #include<ctime> #include<iostream> #include<cmath> using namespace std; int visited[22]={0},a[22]; int primelist[22*2]={0}; int n; bool isprime(int x) { int y; for(y=2;y<=sqrt(x);y++) if (x%y==0) return false; return true; } void dfs(int cur) { if(cur==n+1&&primelist[a[1]+a[n]]) { //for(int i=1;i<n+1;i++) //cout<<a[i]<<" "; //cout<<endl; } else { for(int j=2;j<n+1;j++) { //cout<<cur<<":"<<j<<"--"<<(!visited[j]&&primelist[a[j-1]+j])<<endl; if(!visited[j]&&primelist[a[cur-1]+j]) { visited[j]=1; a[cur]=j; dfs(cur+1); visited[j]=0; } } } } int main() { for(int i=2;i<22*2-1;i++) { if(isprime(i)) primelist[i]=1; } a[1]=1; visited[1]=1; int p=1; while(cin>>n) { clock_t start=clock(),end; for(int i=2;i<22;i++) visited[i]=0; cout<<"Case "<<p++<<":"<<endl; dfs(2); end=clock(); //程式結束用時 double endtime=(double)(end-start)/CLOCKS_PER_SEC; cout<<"Total time:"<<endtime<<endl; //s為單位 } }
使用生成測試法:n=10,耗時183ms
#include<cstdio> #include<algorithm> #include<ctime> #include<iostream> #include<cmath> using namespace std; int primelist[22*2]={0}; int n; bool isprime(int x) { int y; for(y=2;y<=sqrt(x);y++) if (x%y==0) return false; return true; } int main() { for(int i=2;i<22*2-1;i++) { if(isprime(i)) primelist[i]=1; } a[1]=1; visited[1]=1; int p=1,j; while(cin>>n) { clock_t start=clock(),end; for(int i=1;i<n+1;i++) a[i]=i; a[n+1]=1; do{ for(j=1;j<n+1;j++) if(!primelist[a[j]+a[j+1]]) break; if(j==n+1) { for(int i=1;i<n+1;i++) cout<<a[i]<<" "; cout<<endl; } }while(next_permutation(a+2,a+n+1)); end=clock(); //程式結束用時 double endtime=(double)(end-start)/CLOCKS_PER_SEC; cout<<"Total time:"<<endtime<<endl; //s為單位 } }