题意
在正坐标轴上,有 n 个点,其中有一个固定点 0, 之后给我们 n * (n-1)/2 条边,表示某个点到另一个一个点的距离, 现在让我输出,这 n 个点的位置。
思路
首先可以确定两个点,0 点 和 n 个点中距离 0 点最远的那个点,那么我们还有 n - 2 点不确定,因为 n-2 <= 16, 所以我们可以 dfs 暴力枚举求解答案, 那么 dfs 函数怎么写呢,我们先设最长的线段为 len,那么我们考虑从大到小枚举一个长为线段 x,对这个线段要么在距离原点 x 的位置上有一个坐标,要么在距离原点 len-x 的距离上有一个坐标。 加入这个坐标是 x,那么我们首先检查这个的坐标,与我们之前的答案是否冲突,如果 x 点是一个答案,那么我们将之前的答案与现在的 x 形成的线段减去,如果再减去的时候某个线段不存在了,那么这个 x 就符合题意了,如果最终符合题意就加入到 ans 数组中去
代码
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <cstdlib>
#include <queue>
#include <set>
using namespace std;
const int MAX= 2e5 + 5 ;
typedef long long LL;
int flag= 0 ;
int vec[ 433 ] ;
int ans[ 433 ] ;
int vis[ 1000005 ] ;
int n;
int dis;
int top;
bool check ( int ed, int x)
{
int flag= 1 ;
for ( int i= 1 ; i< ed; i++ )
{
vis[ abs ( ans[ i] - x) ] -- ;
if ( vis[ abs ( ans[ i] - x) ] < 0 )
flag= 0 ;
}
for ( int i= 1 ; i< ed; i++ )
{
vis[ abs ( ans[ i] - x) ] ++ ;
}
return flag;
}
void dfs ( int h)
{
if ( h> n)
{
flag= 1 ;
return ;
}
for ( int i= 1 ; i< top; i++ )
{
if ( vis[ vec[ i] ] && vis[ dis- vec[ i] ] )
{
if ( check ( h, vec[ i] ) )
{
ans[ h] = vec[ i] ;
for ( int j= 1 ; j< h; j++ )
vis[ abs ( ans[ j] - vec[ i] ) ] -- ;
dfs ( h+ 1 ) ;
if ( flag) return ;
for ( int j= 1 ; j< h; j++ )
vis[ abs ( ans[ j] - vec[ i] ) ] ++ ;
}
if ( check ( h, dis- vec[ i] ) )
{
ans[ h] = dis- vec[ i] ;
int cnt = dis- vec[ i] ;
for ( int j= 1 ; j< h; j++ )
vis[ abs ( ans[ j] - cnt) ] -- ;
dfs ( h+ 1 ) ;
if ( flag) return ;
for ( int j= 1 ; j< h; j++ )
vis[ abs ( ans[ j] - cnt) ] ++ ;
}
break ;
}
}
}
bool cmp ( int & a, int & b)
{
return a> b;
}
int main ( )
{
int T;
scanf ( "%d" , & T) ;
while ( T-- )
{
flag= 0 ;
memset ( vis, 0 , sizeof vis) ;
memset ( vec, 0 , sizeof vec) ;
memset ( ans, 0 , sizeof ans) ;
scanf ( "%d" , & n) ;
top= n* ( n- 1 ) / 2 ;
for ( int i= 0 ; i< top; i++ )
{
scanf ( "%d" , & vec[ i] ) ;
vis[ vec[ i] ] ++ ;
}
sort ( vec, vec+ top, cmp) ;
dis= vec[ 0 ] ;
ans[ 1 ] = dis;
ans[ 2 ] = 0 ;
vis[ dis] -- ;
dfs ( 3 ) ;
{
sort ( ans+ 1 , ans+ 1 + n) ;
for ( int i= 1 ; i<= n; i++ )
{
if ( i- 1 )
printf ( " %d" , ans[ i] ) ;
else
printf ( "%d" , ans[ i] ) ;
}
}
puts ( "" ) ;
}
}