[LuoguP1286]两数之和
题目描述
题解
假设当前和为:a1,a2,a3……,an
假设a1<a2<a3……<an
那么a1+a2,a1+a3就被确定了
如果我们知道a1和a1+另一个数的和我们就可以算出另一个数
考虑枚举a1,就可以解出a2,a3
那如何解出a4
就需要知道a1+a4,而我们不知道a1+a4和a2+a3的大小关系
但我们已经知道了a2+a3的确切值,所以可以找到a4的值
多组数据好坑。。。
具体看代码
#include<bits/stdc++.h> using namespace std; inline int read() { int f=1,x=0; char ch; do { ch=getchar(); if(ch=='-') f=-1; }while(ch<'0'||ch>'9'); do { x=(x<<3)+(x<<1)+ch-'0'; ch=getchar(); }while(ch>='0'&&ch<='9'); return f*x; } int n; int num; int a[100 + 10]; int ans[100 + 10],top; map<int,int>cnt; inline void print() { for(int i=1;i<=n;i++) { printf("%d ",ans[i]); } cout<<endl; } inline bool dfs(int x) { cnt.clear(); ans[1]=x;ans[2]=a[1]-x;ans[3]=a[2]-x; top=3; cnt[ans[2]+ans[3]]++; for(int i=3;i<=num;i++) { if(cnt[a[i]]) { cnt[a[i]]--; continue; } ans[++top]=a[i]-x; if(top>n) return false; for(int j=2;j<=top-1;j++) { if(ans[top]+ans[j]>a[num]) return false; cnt[ans[top]+ans[j]]++; } } return true; } int main() { while(scanf("%d",&n)==1) { num=n*(n-1)/2; for(int i=1;i<=num;i++) a[i]=read(); sort(a+1,a+num+1); bool flag=0; for(int i=1;i<=a[1]/2;i++) { if(dfs(i)) { flag=1; print(); } } if(!flag) cout<<"Impossible"<<endl; } return 0; }