搜索 HOJ 1226 Lord of the Ring

Lord of the Ring

My Tags   (Edit)
  Source : ACM ICPC Southeastern Europe Regional 2003
  Time limit : 1 sec   Memory limit : 32 M

Submitted : 9, Accepted : 5

Frodo must accomplish a noble and difficult mission, he must destroy a magic and wicked ring. In this quest, he must travel to a dangerous place called Modor and throw the ring into a crevice of fire. He has left home for some time and is currently following a straight and quite long road that has bushes from place to place. Being very tired Frodo thinks he would better have some rest. The only safe place along the road is a bush the position of which can be computed using a magic formula that uses the value P that is the product of the distances between pairs of adjacent bushes along the road. Unfortunately what Frodo knows are only the distances between every pair of bushes along the road and the magic formula, but he doesn't know the value of P. Can you help him in this respect?

The program input is from a text file. Each data set in the file stands for a particular set of distances between pairs of bushes on the road Frodo is traveling along. Each data set starts with the number of distances followed by the distances in nondecreasing order. White spaces can occur freely in the input. For each set of data the program computes the value of P to the standard output from the beginning of a separate line. If P cannot be computed from the data set the output is "No solution".

It is known that there are at least two bushes and at most 1000 bushes along the road. Moreover, the value of P cannot exceed 10^9.

In sample input the second data does not accept a solution. The bush positions along the road cannot be deduced from the data and therefore the distances between adjacent points cannot be computed.

Sample Input
6
1 2 2 3 3 5

3
1 2 2
Sample Output
4
No solution

题意:给出任意两个点之间的距离,要你重构出点的位置。

思路:我是直接搜索的,数据量比较小所以就过了。。。。我们就是根据给出的点之间的距离,然后枚举点的分布情况,添加一个点的时候,跟之前添加过的点求差值,看这些差值还有没有,没有就说明这种情况时不可能的,然后继续枚举。然后添加点的时候不要添加之前已经有的点。我们只要默认起点的位置在0,其他点都在右边,然后根据给出的距离进行枚举就行了,详细请看代码


代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

#pragma comment (linker , "/STACK:102400000,102400000")
const int maxn = 500000;
int dis[maxn];
int cnt[maxn];
int hk[maxn];
int loc[1010];
int sz , n , ans , node_sum;


void init()
{
	sz = 0;
	ans = 1;
	memset(cnt,0,sizeof(cnt));
}

void input()
{
	int x;
	for (int i = 0 ; i < n ; ++i)
	{
		scanf("%d",&x);
		if (sz==0 || dis[sz-1]!=x)
		{
			dis[sz] = x;
			cnt[sz++]++;
		}
		else ++cnt[sz-1];
		hk[i] = sz-1;
	}
}

int Bisearch(int left,int right,int x)
{
	int mid = (left+right)>>1;
	while (left<=right)
	{
		if (dis[mid]==x) return mid;
		else if (dis[mid] < x) left = mid+1;
		else right = mid-1;
		mid = (left+right)>>1;
	}
	return -1;
}

bool dfs(int cur,int rest,int node_cnt)
{
	if (rest==0)
	{
		ans = loc[0];
		for (int i = 1 ; i < node_cnt ; ++i)
			ans *= loc[i]-loc[i-1];
		return true;
	}
	if (cur > n) return false;
	int x = hk[cur];
	bool ok = true;
	loc[node_cnt++] = dis[x] , --cnt[x];
	int *stk = new int [node_cnt+10];
	if (cnt[x] < 0 || (node_cnt > 1 && loc[node_cnt-2]==dis[x])) ok = false;
	int top = 0;
	for (int i = 0 ; i < node_cnt-1 && ok; ++i) 
	{
		int dif = loc[node_cnt-1]-loc[i];
		int p = Bisearch(0,sz-1,dif);
		if (cnt[p]==0) ok = false;
		stk[top++] = p;
	}
	if (ok)
	{
		for (int i = 0 ; i < top ; ++i) --cnt[stk[i]];
		if (dfs(cur+1,rest-node_cnt,node_cnt))
		{
			delete [ ]  stk;
			return true;
		}
		for (int i = 0 ; i < top ; ++i) ++cnt[stk[i]];
	}
	delete [ ] stk;
	--node_cnt , ++cnt[x];
	if (dfs(cur+1,rest,node_cnt)) return true;
	return false;
}

void solve()
{
	if (dfs(0,n,0)) 
		printf("%d\n",ans);
	else 
		printf("No solution\n");
}

int main()
{
//	freopen("input.in","r",stdin);
	while (scanf("%d",&n)==1)
	{
		init();
		input();
		solve();
	}
}


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值