hdu 1518 簡單的回溯
阿新 • • 發佈:2019-02-18
hdu1518 利用搜索外加回溯,每次只搜尋一條邊,當能組成一條邊之後才去搜尋另外一條邊。
visit陣列是用來設定訪問標誌的。
find(x,cnt,k); x當前組成的長度,cnt已經組成了多少正方形的邊了。k已經搜尋到幾根木棍了。
ac程式碼
/************************************************************************* > File Name: backup.cpp > Author: zwy > Mail: [email protected] > Created Time: 2012年11月20日 星期二 11時47分16秒
************************************************************************/ #include<stdio.h> #include<iostream> using namespace std; int ave; int stick[29]; int n; int visit[29]; bool find(int x,int cnt, int k) { int i; if( x == ave) { if(cnt == 2) return true; return find(0,cnt + 1 ,0 ); } if(x <= ave) { for(i = k ; i < n ; i++) if(!visit[i]) { visit[i] = 1; if(find(x + stick[i], cnt ,i+1)) return true; visit[i] = 0 ; } } return false; } int main() { int i; int m,sum; scanf("%d",&m); while(m--) { sum = 0 ; int max = -1; scanf("%d",&n); for(i = 0 ; i < n ; i++) { visit[i] = 0; scanf("%d",&stick[i]); sum += stick[i]; if(max < stick[i]) max = stick[i]; } if(sum % 4 || max > sum / 4) { printf("no\n"); continue; } // printf("************\n"); ave = sum / 4; if(find(0,0,0)) printf("yes\n"); else printf("no\n"); } return 0; }
bug的程式碼。。。一直超時。。
#include<stdio.h> #include<iostream> #include<algorithm> using namespace std; int ave ; int stick[29]; int n; int sum[29]; int visit[29]; /*bool find(int x1,int x2,int x3,int k) { if(x1 == ave && x2 == ave && x3 == ave) { // printf("x1 = %d x2 = %d x3 = %d \n",x1,x2,x3); return true; } else if(x1 <= ave && x2 <= ave && x3 <= ave && k >= 0) { if( x1 + stick[0] > ave && x2 + stick[0] > ave && x3 + stick[0] > ave ) return false; if( x1 + sum[k] < ave || x2 + sum[k] < ave || x3 + sum[k] < ave ) return false; return find(x1 + stick[k],x2,x3,k-1) || find(x1,x2 + stick[k],x3,k-1) || find(x1,x2,x3+stick[k],k-1) || find(x1,x2,x3,k-1); } return false; }*/ bool find(int x1,int cnt,int k) { int i; if(x1 == ave) { cnt ++; if(cnt == 3) return true; x1 = 0 ; k = n - 1; } if(x1 < ave) { for(i = k ; i >= 0 ; i--) if(!visit[i]) { visit[i] = 1; if (find(x1 + stick[i],cnt ,k--)) return true; visit[i] = 0 ; } } return false; } int main() { int i,total; int max; scanf("%d\n",&n); while(scanf("%d",&n)!=EOF) { total = 0; max = -1; for(i = 0 ; i < n ; i++) { scanf("%d",&stick[i]); total += stick[i]; if(max < stick[i]) max = stick[i]; } ave = total / 4 ; sort(stick,stick+n); sum[0] = stick[0]; for(i = 1 ; i < n ; i++) sum[i] = sum[i-1] +stick[i]; for(i = 0 ; i < n ; i ++) visit[i] = 0; //for(i = 0 ; i < n ; i++) // printf("%d ",sum[i]); //printf("\n"); if((double)ave != total * 1.0 / 4 || max > ave) { printf("no\n"); continue; } if(find(0,0,n-1)) { printf("yes\n"); } else { printf("no\n"); } } return 0; }