Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

回复:code

Posted by fjnplx at 2013-02-26 19:51:47 on Problem 1011 and last updated at 2013-02-26 19:54:43
In 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:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator