#10249「一本通 1.3 例 5」weight
题目描述
原题来自:USACO
已知原数列a1,a2,...,an中的前1项,前2项,前3项,... ,前 n 项的和,以及后 1 项,后 2 项,后 3 项,...,后 n 项的和,但是==所有的数都被打乱了顺序==。此外,我们还知道数列中的数存在于集合 S 中。试求原数列。当存在多组可能的数列时,求字典序最小的数列。
输入格式
第 1 行,一个整数 n 。
第 2 行, 2 × n 个整数,注意:数据已被打乱。
第 3 行,一个整数 m ,表示 S 集合的大小。
第 4 行, m 个整数,表示 S 集合中的元素。
输出格式
输出满足条件的最小数列。
样例
样例输入
5
1 2 5 7 7 9 12 13 14 14
4
1 2 4 5
样例输出
1 1 5 2 5
数据范围
题目解析
这道题目的切入口在前几项的和。
我们按照从小到大的顺序排序,从左到右扫
对于 100% 的数据,1≤n≤1000,1≤m≤500 ,且 S∈{1,2,?,500}
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=10005,M=500005;
int read(){
int x=0;char c=getchar();
while(c<‘0‘||c>‘9‘)c=getchar();
while(c>=‘0‘&&c<=‘9‘)x=x*10+c-‘0‘,c=getchar();
return x;
}
int ans[N],sum[N<<1],n,m;bool num[M];
bool flag;
void dfs(int x,int y,int sum1,int sum2,int la){
if(flag)return;
if(x==y){int k=sum[n+n]-sum1-sum2;if(num[k]){ans[x]=k;flag=1;}return;}
if(num[sum[la]-sum1]){ans[x]=sum[la]-sum1;dfs(x+1,y,sum[la],sum2,la+1);}if(flag)return;
if(num[sum[la]-sum2]){ans[y]=sum[la]-sum2;dfs(x,y-1,sum1,sum[la],la+1);}if(flag)return;
}
int main(){
n=read();for(int i=1;i<=n+n;++i)sum[i]=read();
m=read();for(int i=1;i<=m;++i){int x=read();num[x]=1;}
sort(sum+1,sum+1+n+n);
ans[1]=sum[1];
dfs(2,n,ans[1],0,2);
for(int i=1;i<=n;++i)
printf("%d ",ans[i]);
return 0;
}
原文地址:https://www.cnblogs.com/ADMAN/p/10181337.html
时间: 2024-10-31 01:52:01