Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- using namespace std;
- #include <cmath>
- #include <set>
- set<long> bestAverage(double target, long first, long range)
- {
- set<long> ret;
- double bestError = range;
- long bestDivider = 0;
- long bestIncrement;
- long divider;
- if (target < first)
- {
- ret.insert(first);
- return ret;
- }
- if (target > first + range - 1)
- {
- ret.insert(first + range - 1);
- return ret;
- }
- for(divider = 1; divider < range; divider++)
- {
- // find the franctions with given divider we can reach by averaging in the [first, first+range[ range
- double lowerBound = (first + (first + divider - 1)) / 2.0;
- double higherBound = ((first + range - 1) + (first + range - divider)) / 2.0;
- // there exists a set with average in the range [lowerBound, higherBound] of the form n/divider
- double c1 = floor(target * divider) / divider;
- double c2 = ceil(target * divider) / divider;
- double error = min(target - c1, c2 - target);
- if ((lowerBound <= target) && (target <= higherBound) && (error < bestError))
- {
- bestError = error;
- bestDivider = divider;
- if (target - c1 < c2 - target)
- {
- bestIncrement = (long)floor((target - lowerBound) * divider);
- }
- else
- {
- bestIncrement = (long)ceil((target - lowerBound) * divider);
- }
- }
- }
- if (bestDivider == 0)
- {
- return ret;
- }
- long incrementLarge = range - bestDivider; // how many increment (from the least possible average) of 1/divider we make my moving an integer all the way from one side of the range to the other
- long numberLarge = bestIncrement / incrementLarge; // how many integers we move all the way (integer division: rounds down)
- long numberSmall = bestDivider - numberLarge;
- long remainder = bestIncrement - numberLarge * incrementLarge;
- if (remainder > 0)
- {
- numberSmall--;
- }
- for(long index = 0; index < numberSmall; index++)
- {
- ret.insert(first + index);
- }
- if (remainder)
- {
- ret.insert(first + numberSmall + remainder);
- }
- for(long index = 0; index < numberLarge; index++)
- {
- ret.insert(first + range - numberLarge + index);
- }
- return ret;
- }
- int main()
- {
- set<long> answer;
- set<long>::iterator it;
- double target = 3.1415926536;
- double sum = 0;
- cout << "target is " << target << endl;
- answer = bestAverage(target, -100, 200);
- cout << "Average of " << endl;
- for(it = answer.begin(); it != answer.end(); it++)
- {
- cout << *it << ", ";
- sum += *it;
- }
- cout << endl << " is " << sum / answer.size() << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement