| ||||||||||
| 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