题目大意:已知 a1,...,an 这个数列的的 1 到 n 项的前缀和 和 n 到 1 项的后缀和打乱后共 2n 个数,求出字典序最前的可能数组。原题链接
我的做法是带剪枝的dfs,现在40pts,WA了
#include<cstdio>
#include<iostream>
#include<algorithm>
#define int long long
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
{
f=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void write(int x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
{
write(x/10);
putchar(x%10+'0');
return;
}
putchar(x+'0');
}
int n,m,h[2001],a[1001];
bool vis[501];
void dfs(int nw,int l,int r,int cal_l,int cal_r)
{
// for(int i=1;i<=nw;i++)
// {
// cout<<a[i]<<" ";
// }
// cout<<endl;
// cout<<nw<<" "<<l<<" "<<r<<" "<<cal_l<<" "<<cal_r<<endl;
if(!vis[h[nw]-cal_l]&&!vis[h[nw]-cal_r]) return ;
if(l==r)
{
a[l]=h[2*n]-cal_l-cal_r;
if(a[l]<1) return ;
for(int i=1;i<=n;i++)
{
write(a[i]);
putchar(' ');
}
exit(0);
}
if(vis[h[nw]-cal_l])
{
a[l]=h[nw]-cal_l;
dfs(nw+1,l+1,r,h[nw],cal_r);
}
if(vis[h[nw]-cal_r])
{
a[r]=h[nw]-cal_r;
dfs(nw+1,l,r-1,cal_l,h[nw]);
}
}
signed main()
{
n=read();
for(int i=1;i<=2*n;i++) h[i]=read();
sort(h+1,h+2*n+1);
m=read();
for(int i=1;i<=m;i++)
{
int si=read();
vis[si]=1;
}
dfs(1,1,n,0,0);
return 0;
}