hdu 1270
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1270
思路:我们知道排序后sum[1]==num[1]+num[2];sum[2]==num[1]+num[3];但是num[2]+num[3]的值是不确定的,因此我们需要i(3,m)枚举,然后求出num[3]之后,将
num[1]+num[2],num[1]+num[3],num[2]+num[3]的值标记,对于要求的num[4],在sum[]中的一个没有被标记过的一定是num[1]+num[4]的值,求出num[4]之后,在对num[1]+num[4],num[2]+num[4]....进行标记(如果都已标记,说明不成立,退出,再次枚举num[2]+num[3]);此后就可以依此求出num[5]...num[n]...如果最后成功,那么直接退出最外层循环,输出num[1]~num[n];
View Code
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 const int MAXN=110; 8 bool mark[MAXN*MAXN]; 9 int sum[MAXN*MAXN]; 10 int num[MAXN]; 11 /* 12 设所求的n个数按从小到大排列为a1,a2....an。 13 a1+a2一定是n*(n-1)/2个数的序列中最小的,a1+a3一定是次小的,通过枚举a2+a3的值解出符合条件的a1,a2,a3, 14 把他们两两相加的结果从n*(n-1)/2个数中排除,然后n*(n-1)/2个数中剩下的第一个没有被排除的数一定是a1+a4的值, 15 这样可以求的a4,然后再从n*(n-1)/2个数中除去a1+a4,a2+a4,a3+a4,然后n*(n-1)/2个数中剩下的第一个没有被排除 16 的数一定是a1+a5的值,这样可以求的a5,如此重复,直到求的an的值,并除去a1+an,a2+an,....an-1+an,此时如果n*(n-1)/2 17 个数已经全部除去,那么就得到了答案,否则,说明枚举的a2+a3的值仍不合要求,继续枚举下一个a2+a3的值。 18 */ 19 20 21 int main(){ 22 int n; 23 while(~scanf("%d",&n)&&n){ 24 int m=n*(n-1)/2; 25 memset(sum,0,sizeof(sum)); 26 memset(num,0,sizeof(num)); 27 for(int i=1;i<=m;i++)scanf("%d",&sum[i]); 28 sort(sum+1,sum+m+1); 29 for(int i=3;i<=m;i++){ 30 //枚举求出num[1],num[2],num[3]; 31 //num[1]+num[2]一定为sum[1]; 32 //num[1]+num[3]一定为sum[2]; 33 //而num[2]+num[3]的值不确定,因此枚举i(3,m); 34 num[2]=(sum[1]-sum[2]+sum[i])/2; 35 num[1]=sum[1]-num[2]; 36 num[3]=sum[2]-num[1]; 37 if(num[2]+num[3]!=sum[i])continue; 38 39 memset(mark,false,sizeof(mark)); 40 mark[i]=true; 41 int k=3;//从第三个开始排除 42 bool flag=true; 43 for(int j=4;j<=n&&flag;j++){ 44 while(mark[k])k++; 45 num[j]=sum[k]-num[1]; 46 mark[k]=true; 47 //去掉num[2]+num[j],num[3]+num[j],num[4]+num[j]....num[j-1]+num[j]; 48 //那么剩下的第一个没有被排除的数一定是num[1]+num[j+1](此时是下一个循环) 49 for(int l=2;l<j&&flag;l++){ 50 //排除num[j]+num[l](2<=l<=j-1) 51 for(int x=k+1;x<=m;x++){ 52 flag=false; 53 if(!mark[x]&&num[l]+num[j]==sum[x]){ 54 mark[x]=true; 55 flag=true; 56 break; 57 } 58 } 59 } 60 } 61 if(flag)break;//说明此时已经生出n个数 62 } 63 for(int i=1;i<n;i++){ 64 printf("%d ",num[i]); 65 } 66 printf("%d\n",num[n]); 67 } 68 return 0; 69 }