Hi I'v been trying to write Hoare's partition function for like 5 hours now. I read this and this and even straight up copied the "correct" function from these questions and it's still nowhere near the answer. Here is my "translated" code from Cormen's book.
int Hpartition(int A[], int p, int r){
int x = A[p];
int i = p - 1;
int j = r + 1;
while(true){
do{
j--;
}while(A[j] <= x);
do{
i++;
}while(A[i] >= x);
if(i < j){
swap(A[i],A[j]);
}
else
return j;
}
}
QuickSort:
void qs(int A[],int p,int r){
if(p<r){
int q=Hpartition(A,p,r);
qs(A,p,q-1);
qs(A,q+1,r);
}
}
Main:
int main(int argc, const char * argv[]) {
int tab[10];
for(int k=0;k<10;k++){
cin >> tab[k];
}
qs(tab,0,9);
for(int i=0;i<10;i++){
cout << tab[i] << " ";
}
return 0;
}
For this data :
2 4 1 3 5 7 6 8 10 9
It produces this result:
2 4 9 3 5 7 6 8 10 1
Based on the previous questions regarding the topic I know there may be some mistakes in the book. But even when I apply the answers from the previous questions it just won't work .
Here is the algorithm from the book:
HOARE-PARTITION(A, p, r)
1 x = A[p]
2 i = p - 1
3 j = r + 1
4 while TRUE
5 repeat
6 j = j - 1
7 until A[j] <= x
8 repeat
9 i = i + 1
10 until A[i] >= x
11 if i < j
12 exchange A[i] with A[j]
13 else return j
Thanks in advance for any help.
You have 2 error translating code from book:
do{
j--;
}while(A[j] <= x);
You should inverse this:
do{
j--;
}while(A[j] > x);
The same with:
do{
i++;
}while(A[i] >= x);
And one more here:
qs(A,p,q-1);
qs(A,q+1,r);
Change to:
qs(A,p,q);
qs(A,q+1,r);
Related
I am trying to solve:
https://www.spoj.com/problems/ANARC05B/
I am using Binary Search to solve this problem.
I think I have followed the correct approach.
Can anybody help me with a test case that would fail?
Below is my code, it passes on the sample test cases, i dont see a problem with my code but still not sure why i get WA!! Please help!!
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
int BinarySearch(vector<int> arr, int key)
{
int minNum = 0;
int maxNum = arr.size() - 1;
while (minNum <= maxNum)
{
int mid = (minNum + maxNum) / 2;
if (key == arr[mid])
{
return mid;
}
else if (key < arr[mid])
{
maxNum = mid - 1;
}
else
{
minNum = mid + 1;
}
}
return -1;
}
signed long Solve(vector<int> First, vector<int> Second)
{
// Find the intersections in both the arrays and store the indices for them.
vector<int> FirstInterIndices;
vector<int> SecondInterIndices;
for (int i = 0; i < Second.size(); i++)
{
int idx = BinarySearch(First, Second[i]);
if (idx != -1)
{
SecondInterIndices.push_back(i);
FirstInterIndices.push_back(idx);
}
}
if (FirstInterIndices.empty())
{
FirstInterIndices.push_back(FirstInterIndices.size() - 1);
SecondInterIndices.push_back(SecondInterIndices.size() - 1);
}
//Find Intersections ends
//Calc the sum upto intersections in both the arrays and store them
vector<signed long> FirstInterSum;
vector<signed long> SecondInterSum;
for (int i = 0; i < SecondInterIndices.size(); i++)
{
int k = 0;
signed long Sum = 0;
if (i > 0)
{
k = SecondInterIndices[i - 1] + 1;
}
for (; k <= SecondInterIndices[i]; k++)
{
Sum += (signed long)Second[k];
}
SecondInterSum.push_back(Sum);
}
signed long SumLeft = 0;
if (SecondInterIndices.size() > 0)
{
for (int k = SecondInterIndices[SecondInterIndices.size() - 1] + 1; k < Second.size(); k++)
{
SumLeft += (signed long)Second[k];
}
SecondInterSum.push_back(SumLeft);
}
for (int i = 0; i < FirstInterIndices.size(); i++)
{
int k = 0;
signed long Sum = 0;
if (i > 0)
{
k = FirstInterIndices[i - 1] + 1;
}
for (; k <= FirstInterIndices[i]; k++)
{
Sum += (signed long)First[k];
}
FirstInterSum.push_back(Sum);
}
if (FirstInterIndices.size() > 0)
{
SumLeft = 0;
for (int k = FirstInterIndices[FirstInterIndices.size() - 1] + 1; k < First.size(); k++)
{
SumLeft += (signed long)First[k];
}
FirstInterSum.push_back(SumLeft);
}
// Calc sum upto intersections ENDs
// Compare corresponding elements (sum upto intersections) and add the max from First and Second
signed long MaxSum = 0;
int j = 0;
for (; j < FirstInterSum.size(); j++)
{
if (j < SecondInterSum.size())
{
if (FirstInterSum[j] > SecondInterSum[j])
{
MaxSum += FirstInterSum[j];
}
else
{
MaxSum += SecondInterSum[j];
}
}
}
// If Any sum exists after last intersection add that as well.
if (j < FirstInterSum.size())
{
MaxSum += FirstInterSum[FirstInterSum.size() - 1];
}
if (j < SecondInterSum.size())
{
MaxSum += SecondInterSum[SecondInterSum.size() - 1];
}
return MaxSum;
}
vector<int> getArray()
{
vector<int> res;
int n;
cin >> n;
int x;
for (int i = 0; i < n; i++)
{
cin >> x;
res.push_back(x);
}
return res;
}
int main()
{
for (;;)
{
vector<int> First = getArray();
if (First.size() == 0)
return 0;
vector<int> Second = getArray();
cout << Solve(First, Second);
}
return 0;
}
You get WA because the output format is incorrect. I ran your code, and the output looks like this:
13 3 5 7 9 20 25 30 40 55 56 57 60 62
11 1 4 7 11 14 25 44 47 55 57 100
4 -5 100 1000 1005
3 -12 1000 1001
0450
2100
Program ended with exit code: 0
but the expected format should be:
13 3 5 7 9 20 25 30 40 55 56 57 60 62
11 1 4 7 11 14 25 44 47 55 57 100
4 -5 100 1000 1005
3 -12 1000 1001
0
450
2100
Program ended with exit code: 0
difference is 0 and 450 are not on the same line.
But this problem does not require neither binary search nor dynamic programming (as it is marked at the site) and might be solved in linear time (the best possible)
Make two indices - for the first array and for the second one.
At every step move index that refers to smaller element (like in merge procedure of merge sort). When moving, calculate current sum (sum between intersection points).
When both indices point to equal values, you have found intersection point. Choose larger current sum from both arrays, add it and intersection item to result, reset sums to zero.
Pseudocode sketch
if a[ia] < b[ib])
asum += a[ia++]
else
if a[ia] > b[ib])
bsum += b[ib++]
else
result += max(asum, bsum) + a[ia]
asum = bsum = 0
ia++
ib++
A matrix B (consisting of integers) of dimension N × N is said to be good if there exists an array A (consisting of integers) such that B[i][j] = |A[i] - A[j]|, where |x| denotes absolute value of integer x.
You are given a partially filled matrix B of dimension N × N. Q of the entries of this matrix are filled by either 0 or 1. You have to identify whether it is possible to fill the remaining entries of matrix B (the entries can be filled by any integer, not necessarily by 0 or 1) such that the resulting fully filled matrix B is good.
Example
Input 4
2 2
1 1 0
1 2 1
2 3
1 1 0
1 2 1
2 1 0
3 2
2 2 0
2 3 1
3 3
1 2 1
2 3 1
1 3 1
Output
yes
no
yes
no
Here is my code, but failing some tests.
include int main(){
int t;
scanf("%d", &t);
while(t--){
int n, q;
scanf("%d %d", &n, &q);
int arr[n][n];
int brr[n];
for(int i=0;i<n;i++){
brr[i]=1;
for(int j=0;j<n;j++)
arr[i][j]=-1;
}
int result=0;
while(q--){
int l, r, val;
scanf("%d %d %d", &l, &r, &val);
arr[l-1][r-1]=val;
arr[r-1][l-1]=val;
if( abs(brr[l-1]-brr[r-1])!=val && l!=r){
brr[r-1]=brr[r-1]-val;
}
}
for(int i=0;i<n;i++)
printf("%d ", brr[i]);
printf("\n");
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(arr[i][j]!=-1 ){
if( abs(brr[i]-brr[j])==arr[i][j] && abs(brr[i]-brr[j])==arr[j][i]){
continue;
}
else{
result=1;
break;
}
}
}
if(result)
break;
}
if(result)
printf("no\n");
else
printf("yes\n");
}
return 0; }
The question is from live contest : https://www.codechef.com/SEPT17/problems/FILLMTR/. Please focus on learning rather than increase the count of accepted problems.
I have a ribbon, its length is n. I want to cut the ribbon in a way that fulfils the following two conditions:
1. After the cutting each ribbon piece should have length a, b or c.
2. After the cutting the number of ribbon pieces should be maximum.
Find the number of maximum pieces after required cutting.
Input is of the form n,a,b,c where n is the original length of ribbon, and a,b,c are the required lengths of the ribbon.
For eg: I/P = 5 5 3 2
O/P = 2
Now, I am able to realize that this should follow a DP solution. A one dimensional DP where dp[n] represents the maximum number of ways for ribbon of length n.
Now, I am not sure if the recurrence relations will be of the form,
dp[n] = dp[n-a] + a;
dp[n] = dp[n-b] + b;
dp[n] = dp[n-c] + c;
Is this correct or there is some other way?
Edit: Implementation according to the first post:
#include <iostream>
#include <cmath>
using namespace std;
int dp[100000];
int maxi (int a,int b,int c);
int main (void)
{
int n,a,b,c;
cin>>n>>a>>b>>c;
for (int i = 0; i <= n; i++)
{
if ( i == 0 )
dp[i] = 0;
else
dp[i] = maxi(dp[i-a],dp[i-b],dp[i-c])+1;
}
cout<<dp[n]<<"\n";
return 0;
}
int maxi (int a,int b,int c)
{
int ret;
if ( a > b )
ret = a;
else
ret = b;
if ( ret < c )
ret = c;
return ret;
}
if n < 0:
dp[n] = -infinity
if n == 0:
dp[n] = 0
if n > 0:
dp[n] = 1 + max(dp[n-a], dp[n-b], dp[n-c])
for (int i = 0; i <= n; i++)
{
if (i == 0)
dp[i] = 0;
else {
int A = (i-a>=0) ? dp[i-a] : -n-1;
int B = (i-b>=0) ? dp[i-b] : -n-1;
int C = (i-c>=0) ? dp[i-c] : -n-1;
dp[i] = maxi(A,B,C)+1;
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a sequence, which can be really long.
I am inputing the number of elements and the special number, which will cut my sequence into the parts, for example:
10 2
here I have 10 numbers and 5 blocks (10/2)
I must sort this sequence using merge sort
here is the code:
int number_of_elements, k;
cin >> number_of_elements;
cin >> k;
int* massiv_1 = new int[k];
int* massiv_2 = new int[k];
int* resulted_massiv = new int[number_of_elements];
for(int i = 0; i < number_of_elements; i++) {
resulted_massiv[i] = 0;
}
int i = 0;
while( i < number_of_elements) {
int counter_1 = 0;
int counter_2 = 0;
cin >> massiv_1[counter_1];
counter_1++;
if( i != 0 ) {
quick_Sort( massiv_1, k-1 );
for(; counter_2 < k; counter_2++) {
cin >> massiv_2[counter_2];
counter_2++;
}
quick_Sort( massiv_2, k-1 );
merge(massiv_1, k, massiv_2, k, resulted_massiv, i);
}
counter_1 = 0;
counter_2 = 0;
i = i + k;
}
here is the merge sort
void merge(int *a, int a_len, int *b, int b_len, int *c, int z1) {
int i = 0, j = 0;
for(;i < a_len && j < b_len;) {
if(a[i] < b[j]) {
c[z1] = a[i];
++i;
} else {
c[z1] = b[j];
j++;
}
}
if(i == a_len) {
for(; j < b_len; ++j) {
c[z1] = b[j];
}
} else {
for(; i < a_len; ++i) {
c[z1] = a[i];
}
}
}
In other words here is the algorithm:
First I cut sequnce into k parts
I am going through it, if I see the index = k, I am using quick_sort,
then I go to the nearest block and also use quick_sort,
and then I am using merge sorting puting it into other array
...and this I am doing till the end of the sequence
this algorithm doesn't work, if enter this:
10 4
0 4 3 2 1 8 7 6 5 9
it must sort this sequence, but it shows this:
0 0 0 0 4 0 0 0 8 0
I can't get it
I will really appreciate your help, thank you in advance!!!
You always write in single c[z1] element in merge function, and never increment z1 index.
Index in "c" array should be incremented at every step, so you can use c[z1++] everywhere in the funcion
If I enter the numbers:
3 10
7 6
5 5
4 5
the output is : 9. OK — that's the correct value. But if I enter:
10 25
3 5
3 5
3 5
3 5
3 5
3 5
3 5
3 5
3 5
3 5
the correct output should be: 15 but I receive 2005985278.
What's the problem in this code?
#include<stdio.h>
#include<stdlib.h>
#define MA 29
int max(int a, int b) {
return (a > b)? a : b;
}
int knapsack(int W, int P[], int V[], int N)
{
int i, w;
int K[N+1][W+1];
for (i = 0; i <= N; i++)
{
for (w = 1; w <= W; w++)
{
if (i==0 || w==0)
K[i][w] = 0;
else if (P[i-1] <= w)
K[i][w] = max(V[i-1] + K[i-1][w-P[i-1]], K[i-1][w]);
else
K[i][w] = K[i-1][w];
}
}
return K[N][W];
}
int main()
{
int N,W,i;// N: Quantidade de Objetos - W: Capacidade da Mochila; i: interação
int Val=1;//V: Valor;
int Pes=1;//P: Peso;
do{
scanf("%d %d",&N,&W);//ler N e W
for (i=1;i<=N;i++) // iteração
scanf("%d %d",&Val,&Pes);//ler V
//ler P
int V[]={Val};//declaração do vetor V e recebendo Val do scanf
int P[]={Pes};//declaração do vetor P e recebendo Pes do scanf
printf("%d",knapsack(W, P, V, N));
printf("\n");
}while(N!=0 && W!=0);
return 0;
}
I need to enter the number of items N and the capacity W:
When I enter N = 1, W - 7 and the objects P = 4, V = 5 the output is 4.
If I enter other values such as N = 10, W = 25 and P = 3 3 3 3 3 3 3 3 3 3, V = 5 5 5 5 5 5 5 5 5 5, I receive 2005985278 instead of 15.
Please what's the error in my code?
Now my code is this but I receive the erro in my output:
3 10
7 6
5 5
4 5
1 7
4 5
the correct output is : 9 and 4 and i received 7 and 0;
in this case how may i add a end the programm when enter N==0 && W==0?
#include<stdio.h>
#include<stdlib.h>
#define MA 29
int max(int a, int b) {
return (a > b)? a : b;
}
int knapsack(int W, int P[], int V[], int N)
{
int i, w;//interação;
int K[N+1][W+1];//declaração de K recebendo o valor de N e W +1;
for (i = 0; i <=N; i++) // para i=0 i< = N incrementa i;
{
for (w = 0; w <= W; w++)
{
if (i==0 || w==0)
K[i][w] = 0;
else if (P[i-1] <= w)
K[i][w] = max(V[i-1] + K[i-1][w-P[i-1]], K[i-1][w]);
else
K[i][w] = K[i-1][w];
}
}
return K[N][W];
}
int main()
{
int N,W,i;// N: Quantidade de Objetos - W: Capacidade da Mochila; i: interação
//P: Peso;
while (scanf("%d %d", &N, &W) == 2)
{
int V[N];
int P[N];
for (i = 1; i <= N; i++)
if (scanf("%d %d", &V[i], &P[i]) != 2)
break;
printf("%d\n", knapsack(W, P, V, N));
}
}
Your problem is that you are allocating arrays of size 1 and then trying to access 10 elements in those arrays. C won't stop you trying, but it will usually give you the wrong answer.
Existing code:
do{
scanf("%d %d",&N,&W); // Should test for success and terminate loop on failure
for (i=1;i<=N;i++)
scanf("%d %d",&Val,&Pes); // Should check for success; should store values
int V[]={Val}; // V is an array with one entry, the last value entered as Val.
int P[]={Pes}; // P is an array with one entry, the last value entered as Pes.
printf("%d",knapsack(W, P, V, N));
printf("\n");
} while (N!=0 && W!=0);
C99 code:
while (scanf("%d %d", &N, &W) == 2)
{
int V[N];
int P[N];
for (i = 1; i <= N; i++)
if (scanf("%d %d", &V[i], &P[i]) != 2)
break;
printf("%d\n", knapsack(W, P, V, N));
}
Note that if you'd printed the inputs to your knapsack() function, either in the calling code or in the function itself, you'd have seen the trouble very quickly. It is a powerful technique to print your input data after you've finished reading it. Note that printing it while you're reading can mask problems that printing after you've finished reading will reveal.
Clearly, if your knapsack algorithm is incorrect, you'll still get wrong answers; I've not reviewed that and have no particular plans to do so. However, you should be getting the correct input data, which improves enormously the chances of getting the right output.