hdu1270(枚举)

来源:互联网 发布:冰川网络收购棋牌游戏 编辑:程序博客网 时间:2024/06/05 05:34

为了做1280做了这道,WA了n次...........

原理:1,由此枚举ans[2]+ans[3],求出a[1]

原理:2,j从4开始,ans[1]+ans[j+1]<min(ans[1~n]+ans[j+2~n])

原理:3,所以只要将ans[1~n]+a[j]除去,ans[1]+ans[j+1]]就成了最小的和

原理:3,,(由此可知sum[1]=ans[1]+ans[2],sum[2]=ans[1]+ans[3](步骤1原理))

原理:4,j++--->n重复以上步骤

#include <stdio.h>#include <iostream>#include <queue>#include <set>#include <string.h>#include <math.h>#include <algorithm>using namespace std; #define N 110 #define M 5000 int sum[M],ans[N]; bool vis[M]; int main(){     int n,m;     while(scanf("%d",&n),n){        m=n*(n-1)/2;        for(int i=1;i<=m;i++) scanf("%d",&sum[i]);        for(int i=3;i<=m;i++){            ans[2]=(sum[1]-sum[2]+sum[i])/2;            ans[1]=sum[1]-ans[2];            ans[3]=sum[2]-ans[1];            if(ans[2]+ans[3]!=sum[i]) continue;            memset(vis,0,sizeof(vis));            vis[i]=1;            int k=3;//从第三个开始排除            int flag=1;            for(int j=4;j<=n&&flag;j++){                while(vis[k]) k++;                ans[j]=sum[k]-ans[1];                vis[k]=1;                /*排除ans[j]+ans[x](2<=x<j),这样                最小sum就成了ans[j+1]+ans[1]的值*/                for(int  x=2;x<j&&flag;x++)                    for(int y=k+1;y<=m;y++){                            flag=0;                            if(!vis[y]&&ans[x]+ans[j]==sum[y]){                                vis[y]=flag=1;                                break;                            }//if                    }//for_y            }//for            if(flag) break;        }//for        for(int i=1;i<n;i++) printf("%d ",ans[i]);        printf("%d\n",ans[n]);     }//while    return 0; }


0 0
原创粉丝点击