D.
思路:使用map构造两个链表。
#include <bits/stdc++.h>
using namespace std;map<int,int> l,r;
int main()
{int q;cin>>q;int op=-1e9-1;int ed=1e9+1;r[op]=ed;l[ed]=op;while(q--){int a;cin>>a;if(a==1){int x,y;cin>>x>>y;int ll,rr;if(y==0){ll=op,rr=r[op];}else {ll=y,rr=r[y];}r[ll]=x;l[x]=ll;r[x]=rr;l[rr]=x;}else {int x;cin>>x;int ll=l[x],rr=r[x];r[ll]=rr;l[rr]=ll;}}vector<int> f;for (int i=r[op];i!=ed;i=r[i]){f.push_back(i);}cout<<f.size()<<"\n";for (auto i : f){cout<<i<<" ";}}
E.
小红拿到了一个数组,她准备选择若干元素乘以 -1,使得最终所有元素的和为 0。小红想知道最少需要选择多少个元素?
思路:使用dp,设dp为前i项和为j选择元素的最小值,类似于背包问题。
#include <bits/stdc++.h>
using namespace std;
int f[205][80010];int main()
{int n;cin>>n;memset(f,0x3f,sizeof f);f[0][40000]=0;for (int i=1;i<=n;i++){int x;cin>>x;for (int j=0;j<=80000;j++){if(j+x>=0 && j+x<=80000 ) f[i][j]=min(f[i][j],f[i-1][j+x]);if(j-x>=0 && j-x<=80000 ) f[i][j]=min(f[i][j],f[i-1][j-x]+1);//需要乘负一。}}if(f[n][40000]<n) cout<<f[n][40000];else cout<<-1;}