Generating the worst case fot quicksort C++ - c++

I need to create the worst test case for standard quicksort: an array from 1 to N with given size (N can be from 1 to 70000). The key element is the one in the middle. I wrote a recursive function that puts the largest element in the middle (so the algorithm has to compare every element on the left with it) and then splits the array into two parts to put the next biggest elements in the middle of resulting parts. However, my code doesn't pass every case. What could be a problem here?
P. S. my goal is to make the quicksort to do as many comparisons as possible
#include <iostream>
#include <fstream>
using namespace std;
int antiqs(int* array, int start, int end, int maxElement, int* time){
if(end - start < 2) {
return maxElement - *time;
}
int middle = (start + end) / 2;
array[middle] = maxElement - *time;
*time = *time + 1;
antiqs(array, start, middle - 1, maxElement, time);
antiqs(array, middle + 1, end, maxElement, time);
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n;
ifstream fileIn("antiqs.in.txt");
fileIn >> n;
fileIn.close();
int array[n];
for(int i = 0; i < n; i++){
array[i] = 0;
}
int time = 0;
int max = antiqs(array, 0, n-1, n, &time);
ofstream fileOut("antiqs.out.txt");
for(int i = 0; i < n; i++){
if(array[i] == 0){
array[i] = max;
max = max - 1;
}
fileOut << array[i] << " ";
}
fileOut.close();
return 0;
}

Generate a pattern of increasing even numbers followed by decreasing odd numbers. For example:
2 4 6 8 10 7 5 3 1
2 4 6 8 7 5 3 1
2 4 6 7 5 3 1
2 4 6 5 3 1
2 4 5 3 1
2 4 3 1
2 3 1
2 1
1
Example Lomuto partition scheme that uses middle element for pivot:
void QuickSort(int a[], int lo, int hi)
{
while (lo < hi){
std::swap(a[(lo+hi)/2], a[hi]); // use mid point for pivot
int p = a[hi];
int i = lo; // Lomuto partition
for (int j = lo; j < hi; ++j){
if (a[j] < p){
std::swap(a[j], a[i]);
++i;
}
}
std::swap(a[i], a[hi]);
if(i - lo <= hi - i){ // recurse on smaller, loop on larger
QuickSort(a, lo, i-1);
lo = i+1;
} else {
QuickSort(a, i+1, hi);
hi = i-1;
}
}
}

Related

different outputs in different compilers

I am writing a program for a practice coding question
this is the question
Rohan has an array of integers π‘Ž1,π‘Ž2,... π‘Žπ‘› of size 𝑛.
Each integer at index 𝑖 denotes the money placed at that index 𝑖. He can do the following operation exactly once:
Pick a subsegment of the array and cyclically rotate it in the clockwise direction by any amount. i.e. pick integer 𝑙 and π‘Ÿ such that 1β‰€π‘™β‰€π‘Ÿβ‰€π‘›, and rotate the array π‘Žπ‘™,π‘Žπ‘™+1,β€¦π‘Žπ‘Ÿ in the clockwise direction by any amount. Rohan wants the maximum amount of money by performing this particular operation exactly once. After performing the operation, Rohan will collect π‘Žπ‘›βˆ’π‘Ž1 amount of money.
Determine the maximum value of π‘Žπ‘›βˆ’π‘Ž1 that he can obtain.
Input
The first line contains a single integer 𝑑, the number of test cases. Description of the test cases is as follows:
The first line of each test case contains a single integer 𝑛.
The next line contains an array of 𝑛 integers separate by space.
Constraints
1<=𝑑<=100
1<=𝑛<=3000
1<=π‘Žπ‘–<=1000
The sum of 𝑛 over all test cases doesn’t exceed 3000
Output
For each test case, output a single integer indicating the maximum value of π‘Žπ‘›βˆ’π‘Ž1 that Rohan can obtain.
Example
Input:
2
5
1 9 8 4 6
4
3 2 10 8
Output:
8
7
And this is my program
#include <iostream>
#include <climits>
using namespace std;
void cycle(int start, int end, int* arr, int size);
void printArr(int* arr, int size);
int maximum = INT_MIN;
void reInitialize(int* arr, int* arr2, int size);
int main() {
int t, n;
//cout << "enter the number of test cases" << endl;
cin >> t;
while (t != 0) {
cin >> n;
//int data;
int* arr = new int[n];
int* arr2 = new int[n];
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
for (int i = 0; i < n; i++) {
arr2[i] = arr[i];
}
if (arr[n - 1] - arr[0] > maximum) { maximum = arr[n - 1] - arr[0]; }
for (int i = n; i > 1; i--) {
for (int j = 0; j < ((n - i) + 1); j++) {
for (int z = 0; z < i - 1; z++) {
cycle(j, j + (i - 1), arr, i);
if (arr[n - 1] - arr[0] > maximum) { maximum = arr[n - 1] - arr[0]; }
//printArr(arr, n);
}
reInitialize(arr, arr2, n);
}
}
cout << maximum << endl;
delete [] arr;
delete [] arr2;
}
}
void cycle(int start, int end,int *arr, int size) {
if (size <= 0) return ;
int* tempArr = new int[size+1];
int j = 1;
for (int i = start; i <= end-1; i++) {
tempArr[j] = arr[i];
j++;
}
tempArr[0] = arr[end];
j = 0;
for (int i = start; i <= end; i++) {
arr[i] = tempArr[j];
j++;
}
delete[] tempArr;
}
void reInitialize(int* arr, int* arr2, int size){
for (int i = 0; i < size; i++) {
arr[i] = arr2[i];
}
}
while the program works as expected in my gcc compiler when I tried to upload it to the website, this is what the output that i am getting.
Initially I thought this migth be some memory deallocation issue, and I fixed it. but this is the current output that I am getting in that compiler
Input
10
2
6 5
5
2 10 10 9 5
7
3 9 2 1 9 10 9
10
6 10 2 5 10 3 1 9 10 10
10
10 7 5 1 10 10 9 7 3 2
2
9 3
5
7 4 1 9 6
2
7 8
8
9 5 4 9 3 2 3 1
7
5 2 10 7 6 2 1
Expected Output
1\n
8\n
8\n
9\n
4\n
6\n
5\n
1\n
6\n
5
Actual Output
Output too long
Status
Time Limit Exceeded
I would appreciate any help

Trying to make a simple Array sorter with input numbers

I'm very new to C++ or even coding. I was trying to make a simple array sorter, where the I first input the number of elements that will be in the array and then input the elements. My outcome should be the array sorted in ascending order. I have not thought about the case if elements inserted are same. So I would love to get some help from you folks.
The main error that I'm facing is that only the first unsorted element is sorted while the rest are either interchanged or left the same.
int main(){
int x;
cout<<"Enter no. of elements"<<endl;
cin>>x;
int A[x];
for (int i = 0;i<x;i++){
cin>>A[i];
}
for(int i=0;i<x;i++)
cout<<A[i]<<",";
int count=0;
if(count <= (x-1)){
for (int i=0;i<(x-1);i++){
if(A[i]>A[i+1]){
int a;
a = A[i];
A[i] = A[(i+1)];
A[i+1] = a;
}
else if(A[i]<A[i+1])
count++;
}
}
cout<<"Sorted array:";
for(int i=0;i<x;i++)
cout<<A[i]<<",";
return 0;
}
You declared a variable length array
int x;
cout<<"Enter no. of elements"<<endl;
cin>>x;
int A[x];
because its size is not a compile-time constant.
However variable length arrays are not a standard C++ feature though some compilers have their own language extensions that support variable length arrays,
It is better to use the class template std::vector.
Another problem is that it seems you are trying to use the bubble sort method to sort the array. But this method requires two loops.
Here is a demonstration program that shows how the bubble sort algorithm can be implemented.
#include <iostream>
int main()
{
int a[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
const size_t N = sizeof( a ) / sizeof( *a );
for (const auto &item : a)
{
std::cout << item << ' ';
}
std::cout << '\n';
for (size_t last = N, sorted = N; not ( last < 2 ); last = sorted)
{
for (size_t i = sorted = 1; i < last; i++)
{
if (a[i] < a[i - 1])
{
// std::swap( a[i-1], a[i] );
int tmp = a[i - 1];
a[i - 1] = a[i];
a[i] = tmp;
sorted = i;
}
}
}
for (const auto &item : a)
{
std::cout << item << ' ';
}
std::cout << '\n';
}
The program output is
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9
Let us try the following method:
find the largest element in the array and move it to the end, by swapping with the last element;
repeat with the array but the last element, and so on.
To find the largest element in A[0..m-1], scan the array and keep an index to the largest so far, let l. This index can be initialized to 0.
// Move the largest to the end
int l= 0;
for (int i= 1; i < m; i++)
{
if (A[i] > A[l]) l= i;
}
// A[l] is the largest in A[0..m-1]
Swap(A[l], A[m-1]);
// A[m-1] is the largest in A[0..m-1]
To sort, repeat with decreasing m. You can stop when the subarray just holds one element:
// Sort
for (int m= n-1; m > 1; m--)
{
// Move the largest to the end
....
}
Writing the Swap operation and assembling the whole code is your task. Also check
correctness of the Move for the limit cases m= 0, 1, 2.
correctness of the Sort for the limit cases n= 1, 2, 3.
how you could instrument the code to verify that the Move does its job.
how you could instrument the code to verify that the Sort does its job.
what happens in case of equal keys.
Your code can be fixed a bit to make it working.
Just replace if (count <= (x - 1)) with while (count < (x - 1)) and also set count = 0; at start of loop, plus replace else if (A[i] < A[i + 1]) with just else. And your code becomes working!
Necessary fixes I did in code below. Also I did formatting (indents and spaces) to make code looks nicer. Rest remains same.
As I see you have a kind of Bubble Sort.
Try it online!
#include <iostream>
using namespace std;
int main() {
int x;
cout << "Enter no. of elements" << endl;
cin >> x;
int A[x];
for (int i = 0; i < x; i++) {
cin >> A[i];
}
for (int i = 0; i < x; i++)
cout << A[i] << ",";
int count = 0;
while (count < (x - 1)) {
count = 0;
for (int i = 0; i < (x - 1); i++) {
if (A[i] > A[i + 1]) {
int a;
a = A[i];
A[i] = A[(i + 1)];
A[i + 1] = a;
} else
count++;
}
}
cout << "Sorted array:";
for (int i = 0; i < x; i++)
cout << A[i] << ",";
return 0;
}
Input:
10
7 3 5 9 1 8 6 0 2 4
Output:
7,3,5,9,1,8,6,0,2,4,Sorted array:0,1,2,3,4,5,6,7,8,9,
If you are taking the size of array as input from user you have to create your array dynamically in c++ like
int *array=new int(x)
and after taking the inputs of the elements just run a nested loop from 0 to size and
the inner loop from 0 to size-1 and check if(A[i]>A[i+1]) if true then swap the values else continue

Limit chunks of combination in c++

I modified a code I've found on the internet to fit my needs. It calculates and prints all possible combinations of r elements in an array given size of N. Here's the code:
#include <iostream>
#include <vector>
void combinationUtil(std::vector<int> arr, std::vector<int> data, int start, int end, int index, int r);
void printCombination(std::vector<int> arr, int n, int r)
{
std::vector<int> data;
data.assign(r, 0);
combinationUtil(arr, data, 0, n-1, 0, r);
}
void combinationUtil(std::vector<int> arr, std::vector<int> data, int start, int end, int index, int r)
{
if (index == r)
{
for (int j = 0; j < r; j++)
std::cout << data.at(j) << " ";
std::cout << std::endl;
return;
}
for (int i = start; i <= end && end - i + 1 >= r - index; i++)
{
data.at(index) = arr.at(i);
combinationUtil(arr, data, i+1, end, index+1, r);
}
}
int main()
{
std::vector<int> arr = {1, 2, 3, 4, 5};
int r = 3;
int n = arr.size();
printCombination(arr, n, r);
}
The output of it is:
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
I can modify the start value to 1 so the output can start from value 2 like so:
2 3 4
2 3 5
2 4 5
3 4 5
How can I achieve a similar effect for the end. For example if I wanted it to end before calculating combinations starting with value 2. I want to see a result like:
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
I want to do this so I can utilize parallelizations for a larger scale function.
I hope I could relay the idea clear enough. Thanks in advance. (Code compiles with some casting warnings. I just left it like this for an easier read for the reader.)
I solved the issue by modifying another combination method I found on this site.
Here's the code for it:
#include <iostream>
#include <vector>
using namespace std;
vector<int> people;
vector<int> combination;
void pretty_print(const vector<int>& v) {
static int count = 0;
cout << "combination no " << (++count) << ": [ ";
for (int i = 0; i < v.size(); ++i) { cout << v[i] << " "; }
cout << "] " << endl;
}
void go(int offset, int k, int end, bool outermost = true) {
if (k == 0) {
pretty_print(combination);
return;
}
for (int i = offset; i <= people.size() - k; ++i) {
combination.push_back(people[i]);
go(i+1, k-1, end, false);
combination.pop_back();
if(outermost && i == end) return;
}
}
int main() {
int k = 3, end = 1;
people = {1, 2, 3, 4, 5};
go(0, k, end);
return 0;
}
offset controls start and end controls the end.
For loop going on at the outside most layer controls the first element selected for the combination and it progresses as the function recurses.
If statement inside the for loop checks if the wanted line is reached and returns the function prematuraly as needed.

How Vector allocation using push_back() and pop_back operation gives garbage values

I am solving a problem in which I have to find those element from the array whose total gives maximum sum. But there is a condition that no two adjacent element can be the part of that max subarray. Here is my code using simple brute Force solution-
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin >> t;
while (t != 0)
{
int n, i, s, k = 0, m = -1001;
vector< int > a;
cin >> n;
a.resize(n, 0);
vector< int > b;
for (i = 0; i < n; i++)
{
cin >> a[i];
m = max(m, a[i]);
if (a[i] < 0)
{
a[i] = 0;
++k;
}
}
if (k == n)
cout << m;
else
{
k = 0;
s = a[0];
b.push_back(a[0]);
for (i = 1; i < n; i++)
{
if (i != k + 1)
{
if (a[i])
{
s += a[i];
b.push_back(a[i]);
k = i;
}
}
else
{
if (s - a[i - 1] + a[i] > s)
{
b.pop_back();
s -= a[i - 1];
s += a[i];
b.push_back(a[i]);
++k;
}
}
}
}
cout << endl;
for (i = n; i >= 0; i--)
{
if (b[i])
cout << b[i] << " ";
}
cout << endl;
--t;
}
return 0;
}
Here is input to code-
First line represent no. of test cases,
Second line represent size of array
And the next line shows array elements.m
5
5
-1 7 8 -5 4
4
3 2 1 -1
4
11 12 -2 -1
4
4 5 4 3
4
5 10 4 -1
Output-
4 8
32 32607 -787829912 1 3
32 32607 -787829912 12
3 5
10
Expected output-
4 8
1 3
12
3 5
10
So, there are 5 test cases. For the first test case and last two test case output is correct. But for second and third test case it is giving garbage value. What is the problem, that for some test cases it is giving garbage value, and for other not.
for (i = n; i >= 0; i--)
{
if (b[i])
cout << b[i] << " ";
}
This prints out n+1 values in b. But even in the best case, b only has n values (for n=1). And for n>1, b.size() is less than n, so you are reading garbage from outside the vector's storage (this is undefined behavior). Just use the correct bound:
for (i = b.size() - 1; i >= 0; ++i)
I think I found your (first) problem:
if(k==n)
cout<<m;
When all numbers are negative this outputs the largest of them.
But the empty array has a sum of 0 and is larger than a negative number and has no 2 adjacent members in it. So clearly the right answer should be 0, not m.

Solution for SPOJ AGGRCOW

I have the folowing problem:
Farmer John has built a new long barn, with N (2 <= N <= 100,000)
stalls. The stalls are located along a straight line at positions
x1,...,xN (0 <= xi <= 1,000,000,000).
His C (2 <= C <= N) cows don't like this barn layout and become
aggressive towards each other once put into a stall. To prevent the
cows from hurting each other, FJ wants to assign the cows to the
stalls, such that the minimum distance between any two of them is as
large as possible. What is the largest minimum distance?
Input
t – the number of test cases, then t test cases follows.
* Line 1: Two space-separated integers: N and C
* Lines 2..N+1: Line i+1 contains an integer stall location, xi
Output
For each test case output one integer: the largest minimum distance.
Example
Input:
1
5 3
1
2
8
4
9
Output:
3 Output details:
FJ can put his 3 cows in the stalls at positions 1, 4 and 8,
resulting in a minimum distance of 3. Submit solution!
My approach was to pick some pair which has a certain gap and check if there are enough elements in the array to satisfy the need of all the cows.
To find these elements,I used binary search.
When I find an element , I reset my left to mid so I can continue based on the number of cows left.
My code:
#include <iostream>
int bsearch(int arr[],int l,int r,int gap , int n,int c){
int stat = 0;
for (int i = 1;i <= c; ++i) {
while(l <= r) {
int mid = (l+r)/2;
int x = n+(i*gap);
if (arr[mid] > x && arr[mid-1] < x) {
l = mid;
++stat;
break;
}
if(arr[mid] < x) {
l = mid + 1;
}
if (arr[mid] > x) {
r = mid - 1;
}
}
}
if (stat == c) {
return 0;
}
else {
return -1;
}
}
int calc(int arr[],int n , int c) {
int max = 0;
for (int i = 0; i < n; ++i) {
for (int j = i+1;j < n; ++j) {
int gap = arr[j] - arr[i];
if (gap > max) {
if (bsearch(arr,j,n-1,gap,arr[j],c) == 0) {
max = gap;
}
}
}
}
return max;
}
using namespace std;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int t , n ,c;
cin >> t;
for(int i = 0 ; i < t; ++i) {
cin >> n >> c;
int arr[n];
for (int z = 0 ; z < n; ++z) {
cin >> arr[z];
}
sort(arr,arr+n);
//Output;
int ans = calc(arr,n,c);
cout << ans;
}
return 0;
}
Problem Page:
https://www.spoj.com/problems/AGGRCOW/