LOJ P10249 weight 题解
每日一题 day58 打卡
Analysis
这道题搜索的想法非常巧妙,从两端向中间找,这样可以保证仅仅对于head或tail而言,需要用到的前缀和与后缀和是单调递增的,这样排个序就解决了。
值得一提的是,在搜索时开两个变量记录前缀与后缀和,以便计算。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define int long long 6 #define maxn 2000+10 7 #define rep(i,s,e) for(register int i=s;i<=e;++i) 8 #define dwn(i,s,e) for(register int i=s;i>=e;--i) 9 using namespace std; 10 inline int read() 11 { 12 int x=0,f=1; 13 char c=getchar(); 14 while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();} 15 while(c>='0'&&c<='9') {x=x*10+c-'0'; c=getchar();} 16 return f*x; 17 } 18 inline void write(int x) 19 { 20 if(x<0) {putchar('-'); x=-x;} 21 if(x>9) write(x/10); 22 putchar(x%10+'0'); 23 } 24 int n,m; 25 int a[maxn],ans[maxn]; 26 int book[maxn*1000]; 27 int flag=0; 28 void dfs(int num,int head,int tail,int sum_head,int sum_tail) 29 { 30 if(flag==1) return; 31 if(head==tail) 32 { 33 int x=a[2*n]-sum_head-sum_tail; 34 if(x>=1&&x<=500&&book[x]==1) 35 { 36 ans[head]=x; 37 rep(i,1,n) {write(ans[i]); putchar(' ');} 38 flag=1; 39 } 40 } 41 else 42 { 43 int x=a[num]-sum_head; 44 if(x>=1&&x<=500&&book[x]==1) 45 { 46 ans[head]=x; 47 dfs(num+1,head+1,tail,sum_head+x,sum_tail); 48 ans[head]=0; 49 } 50 x=a[num]-sum_tail; 51 if(x>=1&&x<=500&&book[x]==1) 52 { 53 ans[tail]=x; 54 dfs(num+1,head,tail-1,sum_head,sum_tail+x); 55 ans[tail]=0; 56 } 57 } 58 } 59 signed main() 60 { 61 n=read(); 62 rep(i,1,2*n) a[i]=read(); 63 sort(a+1,a+2*n+1); 64 m=read(); 65 rep(i,1,m) 66 { 67 int x=read(); 68 book[x]=1; 69 } 70 dfs(1,1,n,0,0); 71 return 0; 72 }
请各位大佬斧正(反正我不认识斧正是什么意思)