Problem 1098 - 城镇距离
Time Limit: 1000MS
Memory Limit: 65536KB
Difficulty:
Total Submit: 87 Accepted: 13 Special Judge: No
Total Submit: 87 Accepted: 13 Special Judge: No
Description
有N个城镇在一条直线上,并且没有任意两个城镇重叠,他们两两的距离有N*(N-1)/2个,
现在按照这些距离的降序告诉你这N*(N-1)/2个距离,让你求出从左到右他们每两个相邻城镇之间的距离
Input
多组数据
每组数据的第一行为N(N<=20) 代表N个城镇
接下来的若干行有N*(N-1)/2个从大到小排列的数字,降序告诉你这N*(N-1)/2个距离,注意这些数都为小于等于400的正整数
当N=0时结束输入
每组数据的第一行为N(N<=20) 代表N个城镇
接下来的若干行有N*(N-1)/2个从大到小排列的数字,降序告诉你这N*(N-1)/2个距离,注意这些数都为小于等于400的正整数
当N=0时结束输入
Output
对于每组输入,按照字典序输出所有可能的排列情况。每组数据输完后以5个 - 结尾
Sample Input
1
2
2
3
5 3 2
0
2
2
3
5 3 2
0
Sample Output
-----
2
-----
2 3
3 2
-----
2
-----
2 3
3 2
-----
Hint
Source
wudired
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int N,d,l[410],x[410],y[410],v[410],o[410],z[410];
void find(int i)
{
if(i>=d){
int j,flag=0,flag2=0;
z[0]=0;
for(j=1;j<=x[0];j++)if(z[++z[0]]!=x[j])
{if(!flag2)flag2=x[j]>z[z[0]]?1:-1;if(flag2<0)break;z[z[0]]=x[j];flag++;}
for(j=y[0];j>=1;j--)if(z[++z[0]]!=y[j])
{if(!flag2)flag2=y[j]>z[z[0]]?1:-1;if(flag2<0)break;z[z[0]]=y[j];flag++;}
if(flag&&flag2>0)
{
for(j=1;j<z[0];j++)printf("%s%d",j-1?" ":"",z[j+1]-z[j]);
printf("\n");
}
return;
}
if(!v[l[i]]){find(i+1);return;}
v[l[i]]--;
int t,j;
t=y[1]-l[i];
if(!o[t]&&t>x[x[0]]&&t<y[y[0]])
{
int flag=1;
for(j=1;flag&&j<=x[0];j++)if(!v[t-x[j]])flag=0;
for(j=2;flag&&j<=y[0];j++)if(!v[y[j]-t])flag=0;
if(flag)
{
for(j=1;j<=x[0];j++)v[t-x[j]]--;
for(j=2;j<=y[0];j++)v[y[j]-t]--;
{o[t]=1;x[++x[0]]=t;find(i);x[0]--;o[t]=0;}
for(j=2;j<=y[0];j++)v[y[j]-t]++;
for(j=1;j<=x[0];j++)v[t-x[j]]++;
}
}
t=x[1]+l[i];
//if(t==y[1]-l[i])return;
if(!o[t]&&t>x[x[0]]&&t<y[y[0]])
{
int flag=1;
for(j=2;flag&&j<=x[0];j++)if(!v[t-x[j]])flag=0;
for(j=1;flag&&j<=y[0];j++)if(!v[y[j]-t])flag=0;
if(flag)
{
for(j=2;j<=x[0];j++)v[t-x[j]]--;
for(j=1;j<=y[0];j++)v[y[j]-t]--;
{o[t]=1;y[++y[0]]=t;find(i);y[0]--;o[t]=0;}
for(j=1;j<=y[0];j++)v[y[j]-t]++;
for(j=2;j<=x[0];j++)v[t-x[j]]++;
}
}
v[l[i]]++;
}
int
main ( int argc, char *argv[] )
{
int i;
while(scanf("%d",&N)!=EOF)
{
if(!N)break;
d=N*(N-1)/2;
memset(v,0,sizeof(v));
memset(o,0,sizeof(o));
for(i=0;i<d;i++)
{
scanf("%d",&l[i]);
v[l[i]]++;
}
x[0]=1;x[1]=0;
y[0]=1;y[1]=l[0];
v[l[0]]--;
z[1]=-1;
find(1);
printf("-----\n");
}
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */
#include<iostream>
#include<string.h>
#include<math.h>
using namespace std;
int a,b,c,d,e,f;
int dis[405];
int zb[30];
int head,tail;
int n;
int sum,zuida;
int zd,zx,num;
int arr[1000][30];
int moni[30];
int judge(int i)
{
int a,c;
int vis[405];
for (a=zx;a<=zd;a++) vis[a]=dis[a];
//cout<<"FUCK"<<endl;
//for (a=zx;a<=zd;a++) if (dis[a]!=0) cout<<a<<' '<<dis[a]<<endl;
for (a=1;a<=head;a++)
{
c=i-zb[a];
if (vis[c]>0) vis[c]--; else return 0;
}
for (a=tail;a<=n;a++)
{
c=zb[a]-i;
if (vis[c]>0) vis[c]--; else return 0;
}
//for (a=zx;a<=zd;a++) if (dis[a]!=0) cout<<a<<' '<<dis[a]<<endl;
//cout<<"FUCK"<<endl;
return 1;
}
int fuck(int i)
{
int a,c;
for (a=1;a<=head;a++)
{
c=i-zb[a];
dis[c]--;
}
for (a=tail;a<=n;a++)
{
c=zb[a]-i;
dis[c]--;
}
return 1;
}
int pan(int i,int j)
{
int a;
for (a=2;a<=n;a++)
{
int b=arr[i][a]-arr[i][a-1];
int c=arr[j][a]-arr[j][a-1];
if (b>c) return 1;
if (b<c) return 0;
}
return 0;
}
int dfs(int i)
{
int a,b;
//cout<<i<<endl;
//for (a=zx;a<=zd;a++) if (dis[a]!=0) cout<<a<<' '<<dis[a]<<endl;
if (sum==n)
{
for (a=1;a<n;a++) if (zb[a+1]-zb[a]==0) return 0;
for (a=1;a<=num;a++)
{
for (b=1;b<n;b++)
{
if (arr[a][b+1]-arr[a][b]!=zb[b+1]-zb[b]) break;
}
if (b==n) return 0;
}
num++;
for (a=1;a<=n;a++) arr[num][a]=zb[a];
//for (a=1;a<n-1;a++) cout<<zb[a+1]-zb[a]<<' ';
//cout<<zb[n]-zb[n-1]<<endl;
return 0;
}
if (i<=0) return 0;
if (dis[i]==0)
{
int j=i;
while (dis[j]==0 && j>0) j--;
dfs(j);
return 0;
}
//从左
int temp=zb[1]+i;
int vis[405];
for (a=zx;a<=zd;a++) vis[a]=dis[a];
/*
cout<<i<<' '<<temp<<endl;
for (a=1;a<=n;a++) cout<<zb[a]<<' ';
cout<<endl;
for (a=zx;a<=zd;a++) if (dis[a]!=0) cout<<a<<' '<<dis[a]<<endl;
cout<<endl;
*/
if (judge(temp)==1)
{
fuck(temp);
tail--;
zb[tail]=temp;
sum++;
dfs(i);
zb[tail]=0;
sum--;
tail++;
for (a=zx;a<=zd;a++) dis[a]=vis[a];
}
//从右
temp=zb[n]-i;
/*
cout<<i<<' '<<temp<<endl;
for (a=1;a<=n;a++) cout<<zb[a]<<' ';
cout<<endl;
for (a=zx;a<=zd;a++) if (dis[a]!=0) cout<<a<<' '<<dis[a]<<endl;
cout<<endl;
*/
if (judge(temp)==1)
{
fuck(temp);
head++;
zb[head]=temp;
sum++;
dfs(i);
zb[head]=0;
sum--;
head--;
for (a=zx;a<=zd;a++) dis[a]=vis[a];
}
return 0;
}
int main()
{
cin>>n;
while (n!=0)
{
if (n==1) {cout<<"-----"<<endl; cin>>n; continue;}
if (n==2) {cin>>b; cout<<b<<endl; cout<<"-----"<<endl; cin>>n; continue;}
num=0;
zd=0; zx=101010;
zuida=(n-1)*n/2;
memset(dis,0,sizeof(dis));
memset(zb,0,sizeof(zb));
for (a=1;a<=zuida;a++)
{
cin>>b;
dis[b]++;
if (b>zd) zd=b;
if (b<zx) zx=b;
}
/*
for (a=1;a<=n;a++) cin>>moni[a];
for (a=1;a<n;a++)
for (b=a+1;b<=n;b++)
{
zx=min(zx,moni[b]-moni[a]);
zd=max(zd,moni[b]-moni[a]);
dis[moni[b]-moni[a]]++;
}
*/
head=1; tail=n;
zb[head]=1;
zb[tail]=1+zd;
dis[zd]--;
sum=2;
dfs(zd);
for (a=1;a<num;a++)
for (b=a+1;b<=num;b++)
{
if (pan(a,b)==1)
{
for (c=1;c<=n;c++)
{
int temp=arr[a][c];
arr[a][c]=arr[b][c];
arr[b][c]=temp;
}
}
}
for (a=1;a<=num;a++)
{
for (b=2;b<=n;b++)
{
if (b!=n) cout<<arr[a][b]-arr[a][b-1]<<' ';
else cout<<arr[a][b]-arr[a][b-1]<<endl;
}
}
cout<<"-----"<<endl;
cin>>n;
}
return 0;
}