Lord of the Ring
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 Input6 1 2 2 3 3 5 3 1 2 2Sample Output
4 No solution
#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();
}
}