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 |
回复:codeIn Reply To:使用消息传递的思想解决这个问题。 Posted by:fjnplx at 2013-02-26 19:50:42 // the legendary code // 以下英文cut代表剪枝处,cut10暂时未使用 #include <iostream> #include <stdlib.h> //#include <Winsync.h> using namespace std; #define STICKCOUNT 128 int sticks[STICKCOUNT]; bool used[STICKCOUNT] = {false}; int count; int maxval; int minval; int sumval; int completed; int request; int I[STICKCOUNT]; int e_next[STICKCOUNT]; bool chgstk; int uncut; #define MAXLEN (STICKCOUNT*50) int total[MAXLEN];// 总长 int ttcnt; int tttmp; enum{SUCCEED, ABORT, CONTINUE, ROLLBACK, NEXT, CNGSTK}; int revcmp(const void *p, const void *q) { return *((int *)q) - *((int *)p);// 反序 } bool MatchFirstElem() { for(int j = 0; j < completed; j++) if(!used[j]) return false; return true; } int GetCurrentMax() { int max = -1; for(int j = 0; j < count; j++) if(!used[j]) return sticks[j]; return -1; } int GetRemain() { int sumrem = 0; for(int j = 0; j < count; j++) if(!used[j]) sumrem += sticks[j]; return sumrem; } int Judge(int deep) { int i; int _req = request; completed = 0; tttmp = 0; for(i = 0; i <= deep; i++) { tttmp += sticks[I[i]]; if(_req - sticks[I[i]] < 0) return NEXT; _req = (_req - sticks[I[i]] + request) % request; if(_req == 0) { completed++; if(!MatchFirstElem()) return ROLLBACK;// 【massive cut6:首元失配则返回上一级】 _req = request; } if(_req < minval) return NEXT;// 【cut2:小于最小值的排除】 } if(deep+1 == count) { if(completed == sumval / request && sumval % request == 0) return SUCCEED; else// >0 return ROLLBACK; } else// deep != count { if(_req == request) return CNGSTK; else { if(request == _req + sticks[I[i-1]])// is fst if(sticks[I[i-1]] != GetCurrentMax()) return ROLLBACK;//【cut8:首元失配非最值,则返回上一级】 return CONTINUE; } } } int Recursion(int deep) { int i; for(i = (chgstk ? completed : (deep == 0 ? 0 : I[deep-1]+1)); i < count; i++)// 【legendary cut4:第a次从索引第a-1处开始】 {// 【miracle cut5:选择组合时只从大到小选择。】 if(chgstk) chgstk = false; if(!used[i]) { I[deep] = i; int res = Judge(deep); /* // 【wrong cut10:同等总长若有失配过的,跳过(条件为cut5选择组合)】 bool find = false; int index; for(index = 0; index < ttcnt; index++) if(total[index] == tttmp) find = true; if(find) return ROLLBACK; else { if(tttmp % request != 0) total[ttcnt++] = tttmp; }*/ switch(res) { case SUCCEED: used[i] = true; return SUCCEED; case ABORT: return ABORT; case CONTINUE: used[i] = true; break; case CNGSTK: used[i] = true; chgstk = true; break; case ROLLBACK: return ROLLBACK; case NEXT: i = e_next[sticks[i]] - 1;// 【cut3:同值跳过】 if(i == -2) return ROLLBACK; continue; } res = Recursion(deep+1); switch(res) { case SUCCEED: return SUCCEED; case ABORT: return ABORT; case ROLLBACK: used[i] = false; if(GetRemain() % request == 0) if(sticks[i] != GetCurrentMax()) return ROLLBACK;//【cut8:首元失配非最值,则返回上一级】 I[deep] = 0; i = e_next[sticks[i]] - 1;// 【forever cut9:返回时也进行同值跳过】 if(i == -2) return ROLLBACK; break; } } } return ROLLBACK; } int Loop(int val) { int i; // init; uncut = 0; int tmpdeep = 0; for(i = 0; i < count; i++) { if(sticks[i] == val) { used[i] = true; uncut++; I[tmpdeep++] = tmpdeep;// 【cut7:未切割的前置消除】 } else { used[i] = false; I[i] = 0; } } for(i = 0; i < MAXLEN; i++) total[i] = 0; if(tmpdeep == count) return SUCCEED;// 特例(3:1 1 1:1) request = val; completed = 0; chgstk = false; ttcnt = 0; return Recursion(tmpdeep); } int FindMinMaxSum() { int i; sumval = 0; for(i = 0; i < count; i++) sumval += sticks[i]; maxval = sticks[0]; minval = sticks[count-1]; return 0; } int GetNext() { // init int i; for(i = 0; i < STICKCOUNT; i++) e_next[i] = -1; for(i = 1; i < count; i++) { if(sticks[i-1] != sticks[i]) e_next[sticks[i-1]] = i; } return 0; } int main() { int i; cin>>count; while(count != 0) { for(i = 0; i < count; i++) cin>>sticks[i]; //long tick = GetTickCount();// if(count == 1)// 特例(1:3:3) cout<<sticks[0]<<endl; else { qsort(sticks, count, sizeof(int), revcmp);// 反序 GetNext(); FindMinMaxSum(); for(i = maxval; i <= sumval; i++) { if(sumval % i != 0) continue;// 【cut1:必须整除】 int resLoop = Loop(i); if(0 == resLoop) { cout<<i<<endl; break; } } } //cout<<"time ellapse:"<<GetTickCount() - tick<<"ms"<<endl;// //tick = GetTickCount();// cin>>count; } return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator