Problem 1098 - 城镇距离

简介: Problem 1098 - 城镇距离 Time Limit: 1000MS   Memory Limit: 65536KB   Difficulty: Total Submit: 87  Accepted: 13  Special Judge: N...
Problem 1098 - 城镇距离
Time Limit: 1000MS    Memory Limit: 65536KB    Difficulty
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时结束输入
Output
对于每组输入,按照字典序输出所有可能的排列情况。每组数据输完后以5个 - 结尾
Sample Input
1
2
2
3
5 3 2
0
Sample Output
-----
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;
}


目录
相关文章
|
7月前
|
Java
leetcode-452:用最少数量的箭引爆气球
leetcode-452:用最少数量的箭引爆气球
69 0
|
存储
【PAT甲级】1142 Maximal Clique
【PAT甲级】1142 Maximal Clique
60 0
leetcode 452用最少数量的箭引爆气球
leetcode 452用最少数量的箭引爆气球
89 0
leetcode 452用最少数量的箭引爆气球
|
BI
2020ICPC济南站 A . Matrix Equation (高斯消元)
2020ICPC济南站 A . Matrix Equation (高斯消元)
104 0
2020ICPC济南站 A . Matrix Equation (高斯消元)
LeetCode:452. 用最少数量的箭引爆气球
LeetCode:452. 用最少数量的箭引爆气球
98 0
[SDUT 2414] | 山东省第三届省赛 An interesting game | 最小费用最大流
题目描述 Xiao Ming recently designs a little game, in front of player there are N small hillsides put in order, now Xiao Ming wants to increase some hillsides to block the player, so he prepared another M hillsides, but he does not hope it will be too difficult,
165 0
[SDUT 2414] | 山东省第三届省赛 An interesting game | 最小费用最大流
|
存储 机器学习/深度学习 算法
拉开你和别人的距离,只差 Contrastive Learning 这一步
作者提出了 Momentum Contrast 的概念,另外为无监督对比损失函数构建了足够大且具有高度一致性的字典,并通过队列 (queue) 的数据结构进行维护,下图即为 MoCo 论文思路的示意图,动量编码器以及通过队列存储特征向量,便是该文章两大最主要的特点了。
465 0
拉开你和别人的距离,只差 Contrastive Learning 这一步
|
机器学习/深度学习
HDOJ/HDU 2547 无剑无我(两点间的距离)
HDOJ/HDU 2547 无剑无我(两点间的距离)
95 0