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 }

请各位大佬斧正(反正我不认识斧正是什么意思)

原文地址:https://www.cnblogs.com/handsome-zyc/p/12030942.html