题目描述:简而言之就是给一系列数前面加个正负号,使得其和为0.
解题思路:先给这一系列数排序。如果sum是奇数一定不可行,sum必须是偶数才有解,sum/=2,按照从大到小的顺序使sum-trade[i];直到sum为0。为了记录trade[i]在原序列的位置,用一个map来定位,其键就是trade[i]的值,其值是trade[i]相同时,不同的位置,因为本题中只要trade[i]相同,也就是说只要序列中的数相同,就可以。例如不,用考虑是前面那个3是-1还是后面那个3是-1。这样做是正确的,但没证明出来。
代码如下:
#include <iostream> #include <algorithm> #include <deque> #include <cstdio> #include <cstring>
#include <iostream> #include <cstdio> #include <vector> #include <algorithm> #include <cstring> using namespace std; struct node { int value,loc; node(int a,int b):value(a),loc(b){} node(){} }; bool cmp(node a,node b) { return a.value >b.value; } const int maxn=100000+10; int visit[maxn]; vector<node> trade; int main() { int n,x; while(cin >>n) { trade.clear(); memset(visit,0,sizeof(visit)); long long sum=0; for(int i=0;i<n;i++) { scanf("%d",&x); sum+=x; node temp(x,i); trade.push_back(temp); } sort(trade.begin(),trade.end(),cmp); if(sum&1) { cout << "No" << endl; continue; } else { sum/=2; for(int i=0;i<trade.size();i++) { if(sum>=trade[i].value) { sum-=trade[i].value; visit[trade[i].loc]=1; } if(sum==0) break; } cout << "Yes" << endl; for(int i=0;i<n;i++) { if(i!=0) printf(" "); if(visit[i]) cout << "1"; else cout << "-1"; } cout << endl; } } return 0; }
关于证明,瑞神有证明,链接另外对序列中数字排序后其位置改变的处理,我宛如一个智障,用个结构体就解决了。代码如下:#include <iostream> #include <cstdio> #include <vector> #include <algorithm> #include <cstring> using namespace std; struct node { int value,loc; node(int a,int b):value(a),loc(b){} node(){} }; bool cmp(node a,node b) { return a.value >b.value; } const int maxn=100000+10; int visit[maxn]; vector<node> trade; int main() { int n,x; while(cin >>n) { trade.clear(); memset(visit,0,sizeof(visit)); long long sum=0; for(int i=0;i<n;i++) { scanf("%d",&x); sum+=x; node temp(x,i); trade.push_back(temp); } sort(trade.begin(),trade.end(),cmp); if(sum&1) { cout << "No" << endl; continue; } else { sum/=2; for(int i=0;i<trade.size();i++) { if(sum>=trade[i].value) { sum-=trade[i].value; visit[trade[i].loc]=1; } if(sum==0) break; } cout << "Yes" << endl; for(int i=0;i<n;i++) { if(i!=0) printf(" "); if(visit[i]) cout << "1"; else cout << "-1"; } cout << endl; } } return 0; }
第一份代码时间570ms,第二组代码170ms,还是第二份高效啊。