Suitor elimination - c++

I am trying to teach myself C++ and I came across this program project in my book I am working from:
In an ancient land, the beautiful princess Eve had many suitors. She decided on the following procedure to determine which suitor she would marry. First, all of the suitors would be lined up one after the other and assigned numbers.
The first suitor would be number 1, the second number 2, and so on up to the last suitor,number n. Starting at the first suitor she would then count three suitors down the line (because of the three letters in her name) and the third suitor would be eliminated from winning her hand and removed from the line. Eve would then continue, counting three more suitors, and eliminating every third suitor. When she reached the end of the line she would continue counting from the beginning.
For example, if there were six suitors then the elimination process would proceed as follows:
123456 initial list of suitors, start counting from 1
12456 suitor 3 eliminated, continue counting from 4
1245 suitor 6 eliminated, continue counting from 1
125 suitor 4 eliminated, continue counting from 5
15 suitor 2 eliminated, continue counting from 5
1 suitor 5 eliminated, 1 is the lucky winner
Write a program that uses a vector to determine which position you should stand in to marry the princess if there are n suitors. You will find the following function from the Vector class useful:
v.erase(iter);
// Removes element at position iter
For example, to use this function to erase the fourth element from the beginning of a vector variable named theVector , use
theVector.erase(theVector.begin( ) + 3);
The number 3 is used because the first element in the vector is at index position 0.
I have some preliminary code written, but I am having a hard time figuring out how to tell the program after the first suitor (i.e the 3rd suitor) is eliminated to start counting from the fourth suitor, and so on. Perhaps a nested loop would work? I have found solutions online that use a class but it is difficult for me to understand and I feel like there is a simpler way of solving this problem, any help would be greatly appreciated.
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
int n;
vector<int> vec;
cout << "Enter the number of suitors: " << endl;
cin >> n;
// set some values (from 1 to n)
for(int i = 0; i <= n; i++){
vec.push_back(i);
}
// erase third suitor
vec.erase(vec.begin()+2);
// print vector with erased suitor
for(unsigned i = 0; i <= vec.size(); i++){
cout << vec[i] << endl;
}
}

First of all, there are two bugs in your program: you're initially putting [0, n] in the vector, which should be [1, n], and when printing the contents of the vector, you use <= where it should be <.
Now for the actual question. We want to iterate over the vector with steps of size 2 (the second person to the right of the current person):
for (int i = 0; i < vec.size(); i += 2)
However, when we reach the end of the array, we want to continue counting from the front. For this, we can use the modulo operator %:
for (int i = 0; i < vec.size(); i = (i + 2) % vec.size())
This will restrict i to the range [0, vec.size() - 1]. As such, our loop condition is now useless. Instead, we need to take care to terminate the loop when the vector's size is 1:
for (int i = 0; vec.size() > 1; i = (i + 2) % vec.size())
Putting it together, we get the following:
for (int i = 0; vec.size() > 1; i = (i + 2) % vec.size())
vec.erase(vec.begin() + i + 2);
Or equivalently:
for (int i = 2; vec.size() > 1; i = (i + 2) % vec.size())
vec.erase(vec.begin() + i);
The only element that is in the vector when this loop terminates is the number of the lucky suitor.
EDIT: To print out the contents of the vector after each elimination, try this:
for (int i = 2; vec.size() > 1; i = (i + 2) % vec.size())
{
vec.erase(vec.begin() + i);
for (int j = 0; j < vec.size(); j++)
cout << vec[j];
cout << endl;
}

Use relative positioning and take advantage of vec.erase()'s return value.
newpos = vec.erase(pos);
Here 'newpos' is pointing to the element that followed the erased one. Meaning, earsing '3' from {1, 2, 3, 4, 5, 6} gets you pointed to '4'. You can then do
pos = vec.begin();
while (pos != vec.end()) {
erasePos = // compute erasing position relative to 'pos'
// e.g. pos + 2, within bounds
pos = vec.erase(erasePos);
}
You need to do this in a loop.

For that use case where you simply iterate until the end and loop back to the beginning, I would use a list instead of a vector. The program could be :
#include <iostream>
#include <list>
using namespace std;
int main() {
list<int> l;
int n;
int i;
cout << "Enter the number of suitors: ";
cin >> n;
for (i=0; i<n; i++) l.push_back(i);
int delta = 3; // want to remove every third
i = delta;
list<int>::iterator it = l.begin();
while (l.size() > 1) { // loop until only one left
if (--i == 0) { // is it third ?
list<int>::iterator it2 = it++; // move pointer one step further (erase would destroy it)
l.erase(it2); // remove it
i = delta; // rearm counter
}
else it++; // was not third, simply goes on
if (it == l.end()) it = l.begin(); // if at end, go back to begin
}
cout << "Winner is number : " << l.front() + 1 << endl; // add one as our list was 0,1,...n-1
return 0;
}

Related

Cyclical vector - Finding the least possible 'cost' (From CodeChef)

This is a question from Codechef but please bear with me.
https://www.codechef.com/ZCOPRAC/problems/ZCO12004
The contest is for the preparation of the Zonal Computing Olympiad held in India, so its not a competitive contest from which I'd earn something as such. Just need a little help to see what is wrong with my code, because I have a feeling I've overlooked something big and stupid. :P
The problem basically states:
Imagine there is a vector or array such that the last element is
linked to the first one. Find the lowest possible sum from adding at
least one of each adjacent pairs of elements. (refer to link please)
So answer for {1,2,1,2,2} output would be 4 by adding 1+1+2.
Here is my solution:
Basically what it does is that it iterates backwards, from the end of the vector to the beginning, and stores the lowest possible sum that can be achieved from that vector onwards, in vector M. Done using dynamic programming, basically.
The first two elements of M are the possible answers. Then I do some checks to see which is possible. If M[1] is less than M[0] then the last element of the array/vector should have been included in the sum calculated in M[1].
#include <algorithm>
#include <iostream>
#include <vector>
#define print(arr) for(auto pos = arr.begin(); pos != arr.end(); ++pos) cout << *pos << " "; cout << endl;
typedef long long int ll;
using namespace std;
int main() {
int N;
ll x;
cin >> N;
vector <ll> A;
vector <ll> M(N+2);
fill(M.begin(),M.end(),0);
for (int i = 0; i < N; i++) {
cin >> x;
A.push_back(x);
}
for (int i = N-1; i >= 0; i--) {
M[i] = A[i]+*min_element(M.begin()+i+1, M.begin()+i+3);
}
if (M[0] <= M[1]) cout << M[0] << endl;
else if (M[1] < M[0]) {
if (M[N-1] <= (M[N-2])) cout << M[1] << endl;
else cout << M[0] << endl;
}
}
However, I could not pass 2 of the test cases in subtask 2. I think the last part of my code is incorrect. Any idea what I could be doing wrong? Either that, or I have misunderstood the question. The term "adjacent pairs" is sort of ambiguous. So if there are 4 numbers 3,4,5,6 does adjacent pairs mean adjacent pairs to be {(3,4) (4,5) (5,6) (6,3)} or {either (3,4) and (5,6) or (4,5) and (6,3)}? My code considers the former.
EDIT:
Thanks a lot #User_Targaryen cleared some doubts about this question! Basically my implementation was the same as yours as my idea behind using dynamic programming was the same. Only that in this case my M (your dp) was the reverse of yours. Anyway I got AC! :) (I had left some silly debugging statements and was wondering for 15 mins what went wrong xD) Updated solution:
#include <algorithm>
#include <iostream>
#include <vector>
#define print(arr) for(auto pos = arr.begin(); pos != arr.end(); ++pos) cout << *pos << " "; cout << endl;
typedef long long int ll;
using namespace std;
int main() {
int N;
ll x, sum = 0;
cin >> N;
vector <ll> A;
vector <ll> M(N+2);
fill(M.begin(),M.end(),0);
for (int i = 0; i < N; i++) {
cin >> x;
A.push_back(x);
}
for (int i = N-1; i >= 0; i--) {
M[i] = A[i]+*min_element(M.begin()+i+1, M.begin()+i+3);
}
//print(M);
reverse(A.begin(), A.end());
vector <ll> M2(N+2);
fill(M2.begin(),M2.end(),0);
for (int i = N-1; i >= 0; i--) {
M2[i] = A[i]+*min_element(M2.begin()+i+1, M2.begin()+i+3);
}
//print(M2);
cout << min(M[0], M2[0]) << endl;
}
I am attaching my accepted solution here:
#include<iostream>
using namespace std;
int main()
{
int i,j,k,n;
cin>>n;
int a[n],dp1[n],dp2[n];
int ans;
for(i=0;i<n;i++)
{
cin>>a[i];
dp1[i]=0;
dp2[i]=0;
}
if(n <= 2)
cout<< min(a[0],a[1]);
else{
i = 2;
dp1[0] = a[0];
dp1[1] = a[1];
while (i < n){
dp1[i] = a[i] + min(dp1[i-1],dp1[i-2]);
i = i + 1;
}
dp2[0] = a[n-1];
dp2[1] = a[n-2];
i = n-3;
j = 2;
while(i >= 0){
dp2[j] = a[i] + min(dp2[j-1],dp2[j-2]);
i = i - 1;
j = j + 1;
}
ans = min(dp1[n-1], dp2[n-1]);
cout<<ans;
}
return 0;
}
dp1[i] means the most optimal solution till now by including the i-th element in the solution
dp2[i] means the most optimal solution till now by including the i-th element in the solution
dp1[] is calculated from left to right, while dp2[] is calculated from right to left
The minimum of dp1[n-1] and dp2[n-1] is the final answer.
I did your homework!
Edit: #Alex: Dynamic Programming is something that is very difficult to teach. It is something that comes naturally with some practice. Let us consider my solution (forget about your solution for some time):
dp1[n-1] means that I included the last element definitely in the solution, and the constraint that at least one of any 2 adjacent elements need to picked, is satisfied because it always follows:
dp1[i] = a[i] + min(dp1[i-1],dp1[i-2]);
dp2[n-1] means that I included the first element definitely in the solution, and the constraint that at least one of any 2 adjacent elements need to picked, is satisfied also.
So, the minimum of the above two, will give me the final result.
The idea in your M[i] array is "the minimum cost for a solution, assuming the index i is included in it".
The condition if (M[0] <= M[1]) means "if including index 0 is better than not including it, done".
If this condition doesn't hold, then, first of all, the check if (M[1] < M[0]) is superfluous - remove it. It won't fix any bugs, but will at least reduce confusion.
If the condition is false, you should output M[1], but only if it corresponds to a valid solution. That is, since index 0 is not chosen, the last index should be chosen. However, with your data structure it's impossible to know whether M[1] corresponds to a solution that chose last index - this information is lost.
To fix this, consider building two arrays - add e.g. an array L whose meaning is "the minimum cost for a solution, assuming the index i is included in it, and also index N-1 is included in it".
Then, at the end of your program, output the minimum of M[0] and L[1].

a function that takes an array A and index i and rearrange it

Question is: write a function that takes an array A of length n and an index i into A, and rearrange the elments such that all elements less than A[i] appear first, followed by elements equal to A[i], followed by elements greater than A[i].
explanation for my code:
Ask user for n numbers, which is 11. And ask him what the index that he wants to rearrange the elements with. It takes it to function1, and creates a for loop and does an if else statement. if A[i] < A{index} , place it in the begining, else if it's less, place it at the end, or place it in the middle:
Here is my code
#include <iostream>
using namespace std;
void function1(int a[], int ind);
int main()
{
int a[11];
int index;
cout << " enter the numbers: " << endl;
for(int i=0; i < 11; i++)
cin >> a[i];
cout << "what is the index ? " << endl;
cin >> index;
function1(a,index);
}
void function1(int a[], int ind)
{
int x = a[ind];
int newArray[11];
for(int i=0; i < 11; i++)
{
if(a[i] < x)
{
newArray[i] = a[i];
}
else if(a[i] > x)
{
newArray[10-i] = a[i];
}
else
{
newArray[10/2] = a[i];
}
}
for(int i=0; i<11; i++)
cout << newArray[i] << " ";
}
The output that I am expecting to get is the rearrangement of the new array which will probably look similar to this:
a[0....x....n-1], where x is the index that represents a[i]
however I am getting incorrect output with numbers randomly scattered across
what is wrong with my logic ?
The problem is that (like Olaf Dietsche pointed out) you take just one index where two are necessary. Further you can't know if the element that is neither smaller not bigger than a[ind] (means equal to a[ind]) is to be inserted in the middle of the new array. (Imagine 3 2 1 and index 3 results in 2 1 3 but 3 isn't in the middle!)
Updated Version (allows for multiple elements with same value as pivot element)
void rearange(int* data, int size, int pivot)
{
int* temp_data = new int[size];
int start_index = 0, end_index = size - 1;
for (int i = 0; i < size; i++)
{
if (data[i] < data[pivot]) // -> insert 'before' pivot element
{
temp_data[start_index] = data[i];
start_index++;
}
else if (data[i] > data[pivot]) // -> insert 'behind' pivot element
{
temp_data[end_index] = data[i];
endIndex--;
}
// else: skip pivot(s)
}
// insert pivot element(s)
for (int i = start_index; i <= end_index; i++)
{
temp_data[i] = data[pivot];
}
for (int i = 0; i < size; i++)
{
std::cout << temp_data[i] << " ";
}
delete[] temp_data;
}
Input:
11 10 9 8 7 7 7 6 5 4 3
5
Output
6 5 4 3 7 7 7 8 9 10 11
As you see, all elements smaller than element 5 (with value of 7) are before, all elements greater are behind the pivot element. All other elements with same value as pivot are wrapped around position 5, wherever there's free space. However the rearranged elements are not yet sorted (apart from being positioned relative to pivot element)!
You use the same index i for the smaller and larger values. This means, if only the last value a[10] is larger than x, you will write it in the first location newArray[10 - 10], even though you already filled all places up to the 10th. Another problem is, when you have multiple middle values. They will all be stored into newArray[5].
What you want to achieve is called partitioning, as used in the quicksort algorithm.
You need to maintain two indexes (pointers), one for the smaller (left) and one for the larger (right) values.
You have to determine the size of your array at the beginning and pass the fixed size of the array to the function as a parameter.

How to output a missing number in set in c++?

If I have a set in C++, and it contains numbers from 0 to n. I wish to find out the number that is missing from 1 to n and output that and if none of them is missing, then output the number (n+1).
For example, if the set contains, 0 1 2 3 4 5 6 7, then it should output 8
If it contains, 0 1 3 4 5 6, then it should output 2.
I made the following code for this, but it always seems to output 0. I dont know what is the problem.
set<int>::iterator i = myset.begin();
set<int>::iterator j = i++;
while (1)
{
if ( *(j) != *(i)+1 )
{
cout<<*(j)<<"\n";
break;
}
else
{
i++;
j++;
}
}
What is the problem? Thanks!
The problem is that you're advancing i:
set<int>::iterator i = myset.begin(); // <-- i points to first element
set<int>::iterator j = i++; // <-- j points to first element
// i points to second!
while (1)
{ // so if our set starts with {0, 1, ...}
if ( *(j) != *(i)+1 ) // then *j == 0, *i == 1, *i + 1 == 2, so this
// inequality holds
What you meant to do is have j be the next iterator after i:
std::set<int>::iterator i = myset.begin(), j = myset.begin();
std::advance(j, 1);
With C++11, there's also std::next():
auto i = myset.begin();
auto j = std::next(i, 1);
Or, alternatively, just reverse your construction:
std::set<int>::iterator j = myset.begin();
std::set<int>::iterator i = j++; // now i is the first element, j is the second
Or, lastly, you really only need one iterator:
int expected = 0;
for (std::set<int>::iterator it = myset.begin(); it != myset.end();
++it, ++expected)
{
if (*it != expected) {
std::cout << "Missing " << expected << std::endl;
break;
}
}
The easiest stuff: Use count() function of set to check whether an element is present in set or not.
The count() takes an integer argument: The number whose existence in the set is to be checked. If the element is present in set, count() returns a non zero value, else it returns 0.
For example:
#include <iostream>
#include <set>
using namespace std;
int main()
{
set<int> s;
//I insert 0 - 4 in the set.
for(int i=0;i < 5; ++i)
s.insert(i);
//Let 10 be the 'n'.
for(int i = 0; i < 10; ++i)
{
//If i is NOT present in the set, the below condition will be true.
if (!s.count(i))
cout<<i<<" is missing!\n";
}
}
One problem is that you access beyond the end of the set if the set is
dense, which is undefined behavior. Another is that you always output
an element in the set (*j, where j is an iterator into the set);
according to your description, what you want to output is a value which
isn't in the set.
There are a couple of ways of handling this. The simplest is probably
just to maintain a variable expected, initialized with 0 and
incremented each time. Something like the following.
int
firstAvailable( std::set<int> const& allocated )
{
int expected = 0;
for ( auto current = allocated.begin(), end = allocated.end();
current != end && *current == expected;
++ current ) {
++ expected;
}
return expected;
}
If you don't want to return 0 if the list isn't empty, but starts with
some other value, initialize expected with the first element of the
set (or with whatever you want to return if the set is empty).
EDIT:
Of course, other algorithms may be better. For this sort of thing, I usually use a bit map.
The problem with your original code has already been pointed out in the other answers. You're modifying i while assigning j. You can fix this by initializing the iterators as:
set<int>::iterator i = myset.begin();
set<int>::iterator j = i;
j++;
A more elegant solution is to take advantage of the fact that the sum of all values up to n is n * (n + 1) / 2. You can calculate the sum of the actual values, and subtract it from the full sum to obtain the missing value:
int findMissing(const std::set<int>& valSet) {
int valCount = valSet.size();
int allSum = (valCount * (valCount + 1)) >> 1;
int valSum = std::accumulate(valSet.begin(), valSet.end(), 0);
return allSum - valSum;
}
The big advantage of this approach is that it does not rely on using a container where iterators provide the values in sorted order. You can use the same solution e.g. on an unsorted std::vector.
One danger to look out for when using this approach is overflow. With 32-bit ints, it will overflow with approximately 2^16 values. It might actually still work if it overflows, particularly if you use unsigned instead of int, but I did not confirm that.
There's a similar approach that uses the XOR of all values instead of the sum, which does not have the problem with overflow.

2- combination c++

I have an array of n elements, I need to put all 2- combination of them into arrays of length 2. for example:
suppose comb is a 2 dimensional array.
n = 1,2,3
I need to put all 2- combinations to comb[i][j] like that:
comb[0][0] = {1}
comb[0][1] = {2}
comb[1][0] = {1}
comb[1][1] = {3}
comb[2][0] = {2}
comb[2][1] = {3}
I do not know how to write the code!
Thanks
My Answer:
The O(n!) answer: n = total number m= total possible answer
int m = 0;
for (int i = 0; i < n - 1; i++){
int first = a[i];
for(int j = i+1 ; j < n ; j++){
int second = a[j];
comb[m][0] = first;
comb[m][1] = second;
++m;
}
}
Can think of the following N^2 approach:
// Resulting combinations
vector<pair<int,int> > comb;
// Copy n into a double-ended queue - best would be for n to already be a deque
deque<int> Q(a.size());
copy(a.begin(), a.end(), Q.begin());
sort(Q.begin(), Q.end());
while(!Q.empty())
{
// Get first element, remove it and equivalent elements
int a = Q.front();
while(Q.front() == a)
Q.pop_front();
// Find all unique combinations with first element
int last=a;
for(deque<int>::iterator it = Q.begin(); it != Q.end(); ++it)
{
if(*it != last)
comb.push_back(pair<int,int>(a,*it));
last = *it;
}
}
Probably easy to optimize this further.
One easy way is using the next_permutation function available in the STL library in order to generate all the possible permutations of your numbers, and then pick the first two elements of each one. Note that the sequence must be first sorted, as if not the previous permutations will be skipped.
int nums[] = {1, 2, 3, 4};
while (next_permutation(nums, nums + 4)) {
cout << nums[0] << ", " << nums[1] << endl;
}
Remember that you must #include <algorithm> to use this function.
For each element in n indexed ith put every elements in n except the ith indexed jth in cell comb[length(n) - i][j].

Find the biggest 3 numbers in a vector

I'm trying to make a function to get the 3 biggest numbers in a vector. For example:
Numbers: 1 6 2 5 3 7 4
Result: 5 6 7
I figured I could sort them DESC, get the 3 numbers at the beggining, and after that resort them ASC, but that would be a waste of memory allocation and execution time. I know there is a simpler solution, but I can't figure it out. And another problem is, what if I have only two numbers...
BTW: I use as compiler BorlandC++ 3.1 (I know, very old, but that's what I'll use at the exam..)
Thanks guys.
LE: If anyone wants to know more about what I'm trying to accomplish, you can check the code:
#include<fstream.h>
#include<conio.h>
int v[1000], n;
ifstream f("bac.in");
void citire();
void afisare_a();
int ultima_cifra(int nr);
void sortare(int asc);
void main() {
clrscr();
citire();
sortare(2);
afisare_a();
getch();
}
void citire() {
f>>n;
for(int i = 0; i < n; i++)
f>>v[i];
f.close();
}
void afisare_a() {
for(int i = 0;i < n; i++)
if(ultima_cifra(v[i]) == 5)
cout<<v[i]<<" ";
}
int ultima_cifra(int nr) {
return nr - 10 * ( nr / 10 );
}
void sortare(int asc) {
int aux, s;
if(asc == 1)
do {
s = 0;
for(int i = 0; i < n-1; i++)
if(v[i] > v[i+1]) {
aux = v[i];
v[i] = v[i+1];
v[i+1] = aux;
s = 1;
}
} while( s == 1);
else
do {
s = 0;
for(int i = 0; i < n-1; i++)
if(v[i] < v[i+1]) {
aux = v[i];
v[i] = v[i+1];
v[i+1] = v[i];
s = 1;
}
} while(s == 1);
}
Citire = Read
Afisare = Display
Ultima Cifra = Last digit of number
Sortare = Bubble Sort
If you were using a modern compiler, you could use std::nth_element to find the top three. As is, you'll have to scan through the array keeping track of the three largest elements seen so far at any given time, and when you get to the end, those will be your answer.
For three elements that's a trivial thing to manage. If you had to do the N largest (or smallest) elements when N might be considerably larger, then you'd almost certainly want to use Hoare's select algorithm, just like std::nth_element does.
You could do this without needing to sort at all, it's doable in O(n) time with linear search and 3 variables keeping your 3 largest numbers (or indexes of your largest numbers if this vector won't change).
Why not just step through it once and keep track of the 3 highest digits encountered?
EDIT: The range for the input is important in how you want to keep track of the 3 highest digits.
Use std::partial_sort to descending sort the first c elements that you care about. It will run in linear time for a given number of desired elements (n log c) time.
If you can't use std::nth_element write your own selection function.
You can read about them here: http://en.wikipedia.org/wiki/Selection_algorithm#Selecting_k_smallest_or_largest_elements
Sort them normally and then iterate from the back using rbegin(), for as many as you wish to extract (no further than rend() of course).
sort will happen in place whether ASC or DESC by the way, so memory is not an issue since your container element is an int, thus has no encapsulated memory of its own to manage.
Yes sorting is good. A especially for long or variable length lists.
Why are you sorting it twice, though? The second sort might actually be very inefficient (depends on the algorithm in use). A reverse would be quicker, but why even do that? If you want them in ascending order at the end, then sort them into ascending order first ( and fetch the numbers from the end)
I think you have the choice between scanning the vector for the three largest elements or sorting it (either using sort in a vector or by copying it into an implicitly sorted container like a set).
If you can control the array filling maybe you could add the numbers ordered and then choose the first 3 (ie), otherwise you can use a binary tree to perform the search or just use a linear search as birryree says...
Thank #nevets1219 for pointing out that the code below only deals with positive numbers.
I haven't tested this code enough, but it's a start:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> nums;
nums.push_back(1);
nums.push_back(6);
nums.push_back(2);
nums.push_back(5);
nums.push_back(3);
nums.push_back(7);
nums.push_back(4);
int first = 0;
int second = 0;
int third = 0;
for (int i = 0; i < nums.size(); i++)
{
if (nums.at(i) > first)
{
third = second;
second = first;
first = nums.at(i);
}
else if (nums.at(i) > second)
{
third = second;
second = nums.at(i);
}
else if (nums.at(i) > third)
{
third = nums.at(i);
}
std::cout << "1st: " << first << " 2nd: " << second << " 3rd: " << third << std::endl;
}
return 0;
}
The following solution finds the three largest numbers in O(n) and preserves their relative order:
std::vector<int>::iterator p = std::max_element(vec.begin(), vec.end());
int x = *p;
*p = std::numeric_limits<int>::min();
std::vector<int>::iterator q = std::max_element(vec.begin(), vec.end());
int y = *q;
*q = std::numeric_limits<int>::min();
int z = *std::max_element(vec.begin(), vec.end());
*q = y; // restore original value
*p = x; // restore original value
A general solution for the top N elements of a vector:
Create an array or vector topElements of length N for your top N elements.
Initialise each element of topElements to the value of your first element in your vector.
Select the next element in the vector, or finish if no elements are left.
If the selected element is greater than topElements[0], replace topElements[0] with the value of the element. Otherwise, go to 3.
Starting with i = 0, swap topElements[i] with topElements[i + 1] if topElements[i] is greater than topElements[i + 1].
While i is less than N, increment i and go to 5.
Go to 3.
This should result in topElements containing your top N elements in reverse order of value - that is, the largest value is in topElements[N - 1].