I am doing practice questions from geeksforgeeks. And I'm unable to solve the question and get the required output.
https://practice.geeksforgeeks.org/problems/max-sum-path-in-two-arrays/1/?category[]=Arrays&company[]=Amazon&difficulty[]=0&page=1&sortBy=submissions&query=category[]Arrayscompany[]Amazondifficulty[]0page1sortBysubmissions
//I am finding the max path using the merge sort algo, where T(n)=O(m+n)
int MaxPath(int a[],int b[],int n,int m){
int i, j, result=0, sum1=0, sum2=0; // sum1 and sum2 store the sums of 1st and 2nd arrays respectively
while(i<n && j<m){
if(a[i]<b[j]){
sum1+=a[i++];
}
else if(a[i]>b[j]){
sum2+=b[j++];
}
else{
result+=Max(sum1,sum2);
sum1=0;
sum2=0;
int temp=i;
while(i<n && a[i]==b[j]){
sum1+=a[i++];
}
while(j<m && a[temp]==b[j]){
sum2+=b[j++];
}
result+=Max(sum1,sum2);
sum1=0;
sum2=0;
}
}
while(i<n){
sum1+=a[i++];
}
while(j<m){
sum2+=b[j++];
}
result+=Max(sum1,sum2);
return result;
}
Undefined behavior at beginning of code. This statement:
while(i<n && j<m){
Is called before the value of i, or j is set:
int i, j, result=0, sum1=0, sum2=0;
Note that the other items created have been set, but not i and j.
It is therefore undefined from this point on how this while loop will perform. Initialize all variables before they are used.
Related
Given an integer n, write a C program to count the number of digits that are in the same position after forming an integer m with the digits in n but in ascending order of digits. For example, if the value of n is 351462987 then value of m will be 123456789 and digits 4 and 8 will be in the same position.
This is my code:
#include<stdio.h>
void bubble(int a[],int length)
{
for (int i=0;i<length;i++)
{
for (int j=0;j<length;j++)
{
if (a[j]>a[j+1])
{
int t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
}
int check(int a[],int b[],int length)
{
int count=0;
for (int i=0;i<length;i++)
{
if (a[i]==b[i])
{
count=i;
break;
}
}
return count;
}
int length(int n)
{
int l;
while (n!=0)
{
n=n/10;
l++;
}
return l;
}
void main()
{
int n,arrn[100],temp[100];
scanf("%d",&n);
int l=length(n);
for (int i=0;i<l;i++)
{
arrn[l-i-1]=n%10;
temp[l-i-1]=arrn[l-i-1];
n=n/10;
}
bubble(temp,l);
int c=check(arrn,temp,l);
printf("%d",c);
}
I am able to compile the code but when I execute it it takes a long time only to show segmentation fault.
Easy answer, use a debugger.
Here are some problem with your code:
In length function, l is not initialized and as such can have an arbitrary initial value. In your case, you probably want to start at 0.
int l = 0;
Your check function probably don't do what you want. As written count is not a count but the index of a position where numbers match. As there is a break statement in the block, the loop will exit after the first match so the return value would be the position of the first match or 0 if no match was found.
Your bubble function goes one item too far when i is equal to length - 1 as you access item a[j + 1] in the inner loop which is out of bound. In that case, it is simpler to start at 1 instead of 0 and compare item at index i - 1 with item at index i.
Some extra notes:
It is recommended to add whitespace around operators and after a comma separating multiple declarations to improve readability. Here are some example of lines with improved readability.
int n, arrn[100], temp[100];
int count = 0;
for (int i = 0; i < length; i++)…
if (a[i] == b[i])…
arrn[l - i - 1] =n % 10;
temp[l - i - 1] = arrn[l - i - 1];
int check(int a[], int b[], int length)
Instead of writing multiple functions at once, you should write one function and ensure it works properly. By the way, the loop that split a number into digits could also be a function.
Try the function with small number (ex. 12 or 21)
Use better name for your variable. arrn and temp are not very clear. original and sorted might be better.
Your length function has a very obvious bug in it. What value does l start with? You don't initialise it so it could start with any value and cause undefined behaviour. You should set it to 0.
int length(int n)
{
int l = 0;
while (n!=0)
{
n=n/10;
l++;
}
return l;
}
Personally, I wouldn't be sorting or reading it into an int - to enable handling leading zeros in the digit string. For example:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAXNUMLEN 200
int main(void)
{
int i, j, l, x=0;
char numin[MAXNUMLEN], numout[MAXNUMLEN];
int digits[10]={0};
printf("enter a string of digits: " );
fgets(numin, sizeof(numin), stdin);
printf("\nsaw : %s", numin );
// walk string once, counting num of each digit present
l=strlen(numin);
for(i=0; i<l; i++) {
if( isdigit(numin[i]) ) {
int d = numin[i] - '0'; // char digit to int digit
digits[d]++;
}
}
// for each digit present, write the number of instances of the digit to numout
for( i=0; i<10; i++ ) {
for(j=0; j<digits[i]; j++)
numout[x++] = '0'+i; // int digit back to char digit
}
numout[x]='\0'; // terminate string
printf("sorted: %s\n", numout );
}
Sample run:
watson:digsort john$ ./ds
enter a string of digits: 002342123492738234610
saw : 002342123492738234610
sorted: 000112222233334446789
watson:digsort john$
I have just started data structures and I was practicing multiplication of sparse matrice via triplet representation. My code was:
#include<stdio.h>
#include<stdlib.h>
void main(){
int smatrix1[4][3]={{1,2,10},{1,3,12},{2,1,1},{2,3,2}};
int smatrix2[4][3]={{1,1,2},{1,3,8},{2,1,5},{2,2,1}};
int i,j,x=0;
int smatrix3[4][4];
for(int i=0;i<4;){
int r=smatrix1[i][0];
for(int j=0;j<4;j++){
int c=smatrix2[j][0];
int tempa=i,tempb=j;
int sum=0;
while(tempa<=4 && smatrix1[tempa][0]==r && tempb<=4 && smatrix2[tempb][0]==c){
if(smatrix1[tempa][1]<smatrix2[tempb][1])
tempa++;
else if(smatrix1[tempa][1]>smatrix2[tempb][1])
tempb++;
else if(smatrix1[tempa][1]==smatrix2[tempb][1])
sum+=smatrix1[tempa++][2]*smatrix2[tempb++][2];
printf("%d\n",sum);
}
printf("R C SUM %d%d%d\n",r,c,sum);
if(sum!=0){
smatrix3[x][0]=r;
smatrix3[x][1]=c;
smatrix3[x][2]=sum;
x++;
}
while(j<=4 && smatrix2[j][0]==c)
j++;
}
while(i<=4 && smatrix1[i][0]==r)
i++;
}
for(int i=0;i<4;i++){
printf("%d\t%d\t%d\n",smatrix3[i][0],smatrix3[i][1],smatrix3[i][2]);
}
}
While all the elements are printing correctly, the last element results in garbage value. I tried to dry run it but same result. Can anyone please tell me the reason as well as solution?
Edit: I added <=4 instead of <4 incase last element was ignored due to postscript ++ operator. Adding or removing = sign had no effect whatsoever.
EDIT: Here's your problem. This line should not being incrementing j:
Change:
for(int j=0;j<4;j++){
To:
for(int j=0;j<4;){
Also all the comparisons for '<= 4' should be '< 4'
In the problem given here, i have to count total no. of swaps required while sorting an array using insertion sort.
here is my approach
#include <stdio.h>
int main()
{
int t, N, swaps, temp, i, j;
scanf("%d", &t);
while(t--){
scanf("%d", &N);
int arr[N];
swaps = 0;
for(i=0; i<N; ++i){
scanf("%d", &temp);
j=i;
while(j>0 && arr[j-1] > temp){
arr[j] = arr[j-1];
++swaps;
--j;
}
arr[j] = temp;
}
printf("%d\n", swaps);
}
return 0;
}
but, this soln is giving time limit exceeded.
How can i make it more fast?
and, what are the other better solutions of this problem?
this is a standard problem named inversion count
This can be solved using mergesort in O(n*lg(n)). Here is my code for counting the inversions
int a[200001];
long long int count;
void Merge(int p,int q,int r)
{
int n1,n2,i,j,k,li,ri;
n1=q-p+1;
n2=r-q;
int l[n1+1],rt[n2+1];
for(i=0;i<n1;i++)
l[i]=a[p+i];
for(i=0;i<n2;i++)
rt[i]=a[q+1+i];
l[n1]=LONG_MAX;
rt[n2]=LONG_MAX;
li=0;ri=0;
for(i=p;i<=r;i++)
{
if(l[li]<=rt[ri])
a[i]=l[li++];
else
{
a[i]=rt[ri++];
count+=n1-li;
}
}
}
void mergesort(int p,int r)
{
if(p<r)
{
int q=(p+r)/2;
mergesort(p,q);
mergesort(q+1,r);
Merge(p,q,r);
}
}
int main()
{
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
count=0;
mergesort(0,n-1);
printf("%lld\n",count);
}
Basically the problem of inversion count is to find the no. of pairs i and j where j>i such that a[i]>a[j]
To know the idea behind this you should know the basic merge sort algorithm
http://en.wikipedia.org/wiki/Merge_sort
Idea:
Use divide and conquer
divide: size of sequence n to two lists of size n/2
conquer: count recursively two lists
combine: this is a trick part (to do it in linear time)
combine use merge-and-count. Suppose the two lists are A, B. They are already sorted. Produce an output list L from A, B while also counting the number of inversions, (a,b) where a is-in A, b is-in B and a>b.
The idea is similar to "merge" in merge-sort. Merge two sorted lists into one output list, but we also count the inversion.
Everytime a_i is appended to the output, no new inversions are encountered, since a_i is smaller than everything left in list B. If b_j is appended to the output, then it is smaller than all the remaining items in A, we increase the number of count of inversions by the number of elements remaining in A.
This reminds me of a similar problem you may want to look at: http://www.spoj.pl/problems/YODANESS/
In your problem, you can't afford the time to swap everything in case there are many swaps required. (imagine if the input was in reverse order 9,8,7,6.. then you would have to swap everything with everything basically.
I think in your case, each number must be swapped with all the numbers to the left of it that are smaller than it.
I suggest you use a range tree http://en.wikipedia.org/wiki/Range_tree
The great thing about a range tree is each node can know how many nodes are to its left and to its right. You could ask the tree "how many numbers are there greater than 10" very efficiently and that's how many swaps you would have for a 9 say.
The trick is to build the range tree as you move from i=0 to i=N-1. At each point you can query the tree against the ith number before inserting the ith number into the range tree.
good luck!
I did the same code in c++, and it is getting accepted,it is taking time about 4.2 seconds on spoj(http://www.spoj.com/submit/CODESPTB/).
here is the code snippet:
//http://www.spoj.com/problems/CODESPTB/
//mandeep singh #msdeep14
#include<iostream>
using namespace std;
int insertionsort(int arr[], int s)
{
int current,i,j,count=0;
for(i=1;i<s;i++)
{
current=arr[i];
for(j=i-1;j>=0;j--)
{
if(current<arr[j])
{
arr[j+1]=arr[j];
count++;
}
else
break;
}
arr[j+1]=current;
}
return count;
}
int main()
{
int t,n,i,res;
int arr[100000];
cin>>t;
while(t--)
{
cin>>n;
for(i=0;i<n;i++)
{
cin>>arr[i];
}
res=insertionsort(arr,n);
cout<<res<<endl;
}
return 0;
}
#include < stdio.h >
int main() {
int N, swaps, temp[100], i, j;
scanf("%d", & N);
int arr[N];
swaps = 0;
for (i = 0; i < N; i++) {
scanf("%d", & temp[i]);
j = i;
while (j > 0 && arr[j - 1] > temp[i]) {
arr[j] = arr[j - 1];
++swaps;
--j;
}
arr[j] = temp[i];
}
printf("%d", swaps);
return 0;
}
I have currently learning backtracking and got stuck on the 8-queen problem, I am using a 8x8 matrix and I think I've got some problems regarding the matrix passing to functions, any help would be highly apreciated.I wouldn't mind if anyone would bring any optimisation to the code, thanks.
here is my code.
#include <stdio.h>
#include <stdlib.h>
#define MAX 7
//void azzera(int **mat);
void posiziona(int **mat, int r,int c);
void stampa(int **mat);
int in_scacchi(int **mat,int r ,int c);
int main(int argc, char *argv[])
{
int i=0,j=0;
int **mat=(int **)malloc(sizeof(int *)*MAX);
for(i=0;i<=MAX;i++){
mat[i]=(int *)malloc(MAX*sizeof(int));
for(j=0;j<=MAX;j++){
mat[i][j]=-1;
}
}
printf("insert pos of the first queen on the first row (1-8) :");
scanf("%d",&i);
i-=1;
mat[0][i]=1;
posiziona(mat,1,0);
stampa(mat);
system("PAUSE");
return 0;
}
/*void azzera(int **mat){
int i=0,j=0;
for(i=0;i<=MAX;i++){
for(j=0;j<=MAX;j++){
mat[i][j]=-1;
}
}
}*/
void stampa(int **mat){
int i,j;
for(i=0;i<=MAX;i++){
for(j=0;j<=MAX;j++){
printf(" %d",mat[i][j]);
}
printf("\n");
}
}
void posiziona(int **mat, int r,int c){
int i=0,riga=1,flag_col=-1,flag_riga=-1;
if(riga<=7&&flag_riga!=1){
if(flag_riga==1){
flag_riga=-1;
posiziona(mat,r+1,0);
}
else if(in_scacchi(mat,r,c)==1){
if(c==MAX)
posiziona(mat,r-1,0);
posiziona(mat,r,c+1);
}
else{
flag_riga=1;
}
}
}
int in_scacchi(int **mat,int r ,int c){
int i,j,k,m;
int flag=0;
//col
for(i=0;i<r;i++){
for(j=0;j<=c;j++){
if(((mat[i][j]==1)&&(c==j)))
return 1;
}
}
//diag \
for(i=0;i<MAX-r;i++){
for(j=0;j<=MAX-c;j++){
if(mat[MAX-r-i][MAX-c-j]==1)
return 1;
}
}
//antidiag
for(i=r+1;i<=MAX;i++){
for(j=c+1;j<=MAX;j++){
if(mat[r-i][c+j]==1) {
return 1;
}
}
}
return 0;
}
1. One glaring problem is the memory allocation:
int **mat=(int **)malloc(sizeof(int *)*MAX);
for(i=0;i<=MAX;i++){
mat[i]=(int *)malloc(MAX*sizeof(int));
Given that MAX is 7, both mallocs are allocating too little memory for the matrix (seven elements instead of eight).
To be honest, I'd rename MAX to SIZE or something similar, and change all your loops to use strict less-than, i.e.
for(i = 0; i < SIZE; i++) {
I would argue that this is slightly more idiomatic and less prone to errors.
2. I haven't tried to debug the logic (I don't think it's fair to expect us to do that). However, I have noticed that nowhere except in main do you assign to elements of mat. To me this suggests that the code can't possibly be correct.
3. Beyond that, it may be useful to observe that in a valid solution every row of the chessboard contains exactly one queen. This means that you don't really need an 8x8 matrix to represent the solution: an 8-element array of column positions will do.
edit In response to your question in the comments, here is a complete Python implementation demonstrating point 3 above:
def can_place(col_positions, col):
row = len(col_positions)
for r, c in enumerate(col_positions):
if c == col or abs(c - col) == abs(r - row): return False
return True
def queens(n, col_positions = []):
if len(col_positions) >= n:
pretty_print(n, col_positions)
return True
for col in xrange(n):
if can_place(col_positions, col):
if queens(n, col_positions + [col]):
return True
return False
def pretty_print(n, col_positions):
for col in col_positions:
print '.' * col + 'X' + '.' * (n - 1 - col)
queens(8)
Your matrix must iterate from 0 to MAX-1,
i.e
int **mat= malloc(sizeof(int *)*MAX);
for(i=0;i< MAX;i++){ //see for i<MAX
mat[i]= malloc(MAX*sizeof(int));
for(j=0;j<MAX;j++){ //see for j<MAX
mat[i][j]=-1;
}
}
malloc must be called with sizeof(...) * (MAX+1) in both the i- and j-loop.
Moreover, when I ran your program I got an access violation in the antidiag portion of in_scacchi(...) due to the fact that the code tries to access mat[r-i][c+j] which evaluates to mat[-1][1] because r==1 and i==2.
So there seems to be a logical error in your description of the anti-diagonal of the matrix.
I made a merge sort function:
void mergeSort(int emotionCount[], int low, int high){
int i=0,k=0;
//I did this to see the value inside the array, and I always got a garbage value
//when i=0, and the first correct value when i=1. I made a for loop here to
//see the values in the array in debugging mode in netbean.
for (i=0;i<=high;i++){
}
if (low == high){
emotionCount[low]=emotionCount[low];
}else{
int mid = (low+high)/2;
mergeSort(emotionCount,low,mid);
mergeSort(emotionCount,mid+1,high);
merge(emotionCount, low,mid, high); }
}
void merge(int emotionCount[], int low,int mid, int high)
{
int temp[high-low+1];
int i=low,k=mid+1, j=high, n=0;
int comparing=emotionCount[k];
while (i<=mid || k<=high){
while (emotionCount[i]<comparing)
{
temp[n]=emotionCount[i];
i++;
n++;
}
comparing=emotionCount[i];
temp[n]=emotionCount[k];
k++;
i++;
n++;
while (emotionCount[k]<comparing){
temp[n]=emotionCount[k];
k++;
n++;
}
comparing=emotionCount[k];
temp[n]=emotionCount[i];
k++;
i++;
n++;
}
while (i<=mid)
{
temp[n]=emotionCount[i];
i++;
n++;
}
while (k<=high)
{
temp[n]=emotionCount[k];
k++;
n++;
}
while (low<=high)
{
emotionCount[low]=temp[i];
low++;
}
}
And in main, i pass an array:
int array[10] = {0,5,8,2,4,6,8,2,20,25};
//number 9 because the highest position is 9. After this, array[10] is supposed to be sorted.
mergeSort(array ,0, 9);
Well, the method was kinda long, but I want to implement it myself. Basically, I pass an array to the mergeSort function, and if it is not at its minimum size (which is 1), it will continue to pass that array. The thing which bugging me is, when I pass an array to it, the first value is always a garbage value (like an address value or something). Only after i=1, it will give the first value of the array. I don't get it. Also, everytime exiting a lower mergeSort function to continue on the higer ones, all the sorted values in the array become 0.
Edit: The k variable is just used to hold the array value, to see the array value when I'm in debugging mode. I removed the k variable in the mergeSort function to clear up the confusion.
Yet to read through your function, but at first glance the problem that stands out is the way you are calling the function.
It should be :
mergeSort(array, 0, 9);
If you use array[10], it means you're trying to pass in the 11th element of the array which is unfortunately out of bounds!
It looks like you're passing a value from inside the array instead of the array itself: shouldn't
mergeSort(array[10] ,0, 9);
be something like
mergeSort(array, 0, 0);
for (i=0;i<=high;i++){
int k=*(emotionCount+i);
}
if (low == high){
emotionCount[low]=emotionCount[low];
int k=emotionCount[low];
}else{
int mid = (low+high)/2;
mergeSort(emotionCount,low,mid);
int i=0;
for (i=low;i<=mid;i++){
int k=emotionCount[i];
}
mergeSort(emotionCount,mid+1,high);
for (i=mid+1;i<=high;i++){
int k=emotionCount[i];
}
merge(emotionCount, low,mid, high);
for (i=low;i<=high;i++){
int k=emotionCount[i];
}
}
You redeclare int k in all those blocks. I assume you want to assign a value to k instead so remove the leading "int". Just as in Java which you claim to be familiar with.
What do you want to do anyway? Even if you would use your globally declared k assigning all array elements in a loop doesn't make sense at all. Basically you would end up with k being equal to emotionCount[high].
Do you know that you can dereference array elements using the [] syntax?
k = emotionCount[i]
Is easier to read.
You use Netbeans which has a nice GDB frontend. I suggest that you set a few breakpoints, step through your code and try to understand what you implemented there.
I solved the problem. Corrected code:
void mergeSort(int emotionCount[], int low, int high){
int i=0,k=0;
if (low == high){
emotionCount[low]=emotionCount[low];
k=emotionCount[low];
}else{
int mid = (low+high)/2;
mergeSort(emotionCount,low,mid);
/*
int i=0;
printf("Lower half:");
for (i=low;i<=mid;i++){
k=emotionCount[i];
printf("%d ",k);
}
printf("\n");*/
mergeSort(emotionCount,mid+1,high);
/*
printf("Upper half:");
for (i=mid+1;i<=high;i++){
k=emotionCount[i];
printf("%d ",k);
}
printf("\n");*/
merge(emotionCount, low,mid, high);
//this is how I view the sorting process, along with other 2 above loops
/* printf("Merged:");
for (i=low;i<=high;i++){
k=emotionCount[i];
printf("%d ",k);
}
printf("\n\n");*/
}
}
void merge(int emotionCount[], int low,int mid, int high)
{
int temp[high-low+1],index;
for (index=0;index<high-low+1;index++)
{
temp[index]=0;
}
int i=low,k=mid+1, j=high, n=0;
int comparing=emotionCount[k],temp1;
while (i<=mid && k<=high){
while (emotionCount[i]<comparing && i<=mid)
{
temp[n]=emotionCount[i];
i++;
n++;
}
if (i<=mid){
comparing=emotionCount[i];
if (k<=high)
temp[n]=emotionCount[k];
else
temp[n]=comparing;
k++;
n++;
}
while (emotionCount[k]<comparing && k<=high){
temp[n]=emotionCount[k];
k++;
n++;
}
if (k<=high){
comparing=emotionCount[k];
if (i<=mid)
temp[n]=emotionCount[i];
else
temp[n]=comparing;
i++;
n++;
}
}
while (i<=mid)
{
temp[n]=emotionCount[i];
i++;
n++;
}
while (k<=high)
{
temp[n]=emotionCount[k];
k++;
n++;
}
i=0;
while (low<=high)
{
emotionCount[low]=temp[i];
low++;
i++;
}
}
The initial high value must be exactly array size - 1.