Showing posts with label sum range. Show all posts
Showing posts with label sum range. Show all posts

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

}
}