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;
}