Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
reference code#include <iostream> #include <cstdlib> #include <memory> using namespace std; int S,L; int anLength[65],anUsed[65];//记录木棍的长度和访问标记 int nLastStickNo=0;//最近拼上去的那条木棒的下标 int DFS(int,int); int cmp(const void *a,const void *b)//按降序 {return *(int *)b-*(int *)a;} int main() { while(1) { cin>>S; if(S==0) break; int nTotalLen=0; for(int i=0;i<S;i++)///输入每个棍子长度并记录总共长度 { cin>>anLength[i]; nTotalLen+=anLength[i]; } qsort(anLength,S,sizeof(int),cmp); for(L=anLength[0];L<=nTotalLen/2;L++)//新组成的长度必然大于等于原来中最大的 { if(nTotalLen%L)//必须保证分成整数几段 continue; memset(anUsed,0,sizeof(anUsed));//清零 if(DFS(S,L)) { cout<<L<<endl; break; } }if(L>nTotalLen/2) { cout<<nTotalLen<<endl; } } } int DFS(int nUnusedSticks,int nLeft)//// nLeft表示当前正在拼的棍子和 L比还缺的长度 { if(nUnusedSticks==0&&nLeft==0)//所有的木棍都用过了并且要拼的木棍的长度是0完成了拼凑返回真值 return true; if(nLeft==0)////一根刚刚拼完 nLeft=L;//开始拼新的一根 int nStartNo=0; if(nLeft!=L)//剪枝4 nStartNo=nLastStickNo+1; for(int i=nStartNo;i<S;i++) { if(!anUsed[i]&&anLength[i]<=nLeft) { if(i>0) { if(anUsed[i-1]==false&&anLength[i]==anLength[i-1])//剪枝 3 //上一根同样长度的木棒为什么还没用?必然是因为刚刚用过,并且发现用了后不行,才将其 anUsed标志置回0 continue; } anUsed[i]=1; nLastStickNo=i;//最近拼上去的那条木棒的下标 if(DFS(nUnusedSticks-1,nLeft-anLength[i]))///表示判断是否已经拼完了一个符合的新木棍 return true; else { anUsed[i]=0;;//说明本次不能用第i根,以后还有用 if(anLength[i]==nLeft||nLeft==L)//剪枝2,1 return false; } } } return false; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator