AOJ 1307 ICPC Asia resional 2010 Problem C: Towns along a Highway
問題
数直線状にn個の点が並んでいる。
一番左側の点のx座標は0である。
各二点間の距離を表す行列(の上半分)が、要素だけを大きい順に並べた形で与えられる。
このときもとの行列を復元せよ。
制約条件
n≦18
d[i]≦400
ソースコード
int n,d[200],cnt[401]; set<vi> ans; vi tmp; void rec(int c,int right){ //cerr<<c<<" "<<right<<endl; //rep(i,tmp[0]+1)if(cnt[i])rep(j,cnt[i])cerr<<i<<" "; cerr<<endl; if(c==n){ vi d,e=tmp; sort(all(e)); rep(i,n-1)d.pb(e[i+1]-e[i]); if(!ans.count(d))ans.insert(d); return; } int mx=right; for(;mx>=0&&cnt[mx]==0;mx--); if(mx<0)return; rep(it,2){ tmp.pb(mx); bool ok=1; rep(i,c)if(--cnt[abs(tmp[i]-mx)]<0)ok=0; if(ok)rec(c+1,it?tmp[0]-mx:mx); rep(i,c)cnt[abs(tmp[i]-mx)]++; tmp.erase(tmp.begin()+c); if(mx==tmp[0]-mx)break; mx=tmp[0]-mx; } } int main() { while(cin>>n,n){ ans.clear(); rep(i,401)cnt[i]=0; rep(i,n*(n-1)/2)cin>>d[i],cnt[d[i]]++; int mx=*max_element(d,d+n*(n-1)/2); tmp.clear(); tmp.pb(mx); tmp.pb(0); cnt[mx]--; rec(2,mx); fr(i,ans)rep(j,n-1)cout<<(*i)[j]<<(j==n-2?"\n":" "); cout<<"-----"<<endl; } return 0; }