Saturday, February 23, 2013

sum range (a lot of stl!!)

find the range that sum up to a closest value to a given value


#include<set>
#include<vector>
#include<algorithm>
#include<iostream>
#include<iterator>
using namespace std;

struct ltstr
{
bool operator()(pair<int,int> p1, pair<int,int> p2) const
{
return p1.first<p2.first;
}
};

void FindRange(vector<int> X,int val,int& startId, int& endId)
{
int size=X.size();

//preprocessing sum
set<pair<int,int>,ltstr> sum;
vector<pair<int,int>> my_vec;
int cur_sum=0;
for(int i=0;i<=size;i++)
{
sum.insert(pair<int,int>::pair(cur_sum,i));
my_vec.push_back(pair<int,int>::pair(cur_sum,i));
if(i<size)cur_sum+=X[i];
}

int closest=INT_MAX;
for(vector<pair<int,int>>::iterator iter=my_vec.begin();iter!=(my_vec.end()-1);iter++)
{
//remove already searched range so the output range is valid
pair<int,int> to_erase=*iter;
sum.erase(*iter);

int to_search=(*iter).first+val;
//search for closest value with lower bound and upper bound
set<pair<int,int>,ltstr>::iterator lower_bound=sum.lower_bound(pair<int,int>::pair(to_search,0));
set<pair<int,int>,ltstr>::iterator upper_bound=lower_bound;
if(lower_bound!=sum.begin())
upper_bound--;
if(lower_bound==sum.end())
lower_bound--;
int cur_min=min(abs((*lower_bound).first-to_search),abs((*upper_bound).first-to_search));
if(cur_min<closest)
{
closest=cur_min;
startId=iter-my_vec.begin();
endId=abs((*lower_bound).first-to_search)<abs((*upper_bound).first-to_search)?(*lower_bound).second-1:(*upper_bound).second-1;
}

}
}

No comments:

Post a Comment