to break the tree in even number of nodes - c

You are given a tree (a simple connected graph with no cycles).
Find the maximum number of edges you can remove from the tree to get a forest such that each connected component of the forest contains an even number of nodes.
https://www.hackerrank.com/challenges/even-tree/problem
In the above link the test cases are given. For sampple input 1, I am getting 0 as output instead of expected value 2.
#include<stdio.h>
#include<stdlib.h>
int ans = 0;
int v, e;
int visited[201];
int gph[201][201];
int dfs(int i) {
int num_nodes;
int num_vertex = 0;
visited[i] = 1;
for (int j = 1; j <= v; j++) {
if (visited[i] == 0 && gph[i][j] == 1) {
num_nodes = dfs(j);
if (num_nodes % 2 == 0)
ans++;
else
num_vertex += num_nodes;
}
}
return num_vertex + 1;
}
int main() {
scanf("%d %d", &v, &e); // vertices and edges
int u, v;
for (int i = 0; i < e; i++) {
scanf("%d %d", &u, &v); //edges of undirected graph
gph[u][v] = 1;
gph[v][u] = 1;
}
dfs(1);
printf("%d", ans);
}
Test case:
10 9
2 1
3 1
4 3
5 2
6 1
7 2
8 6
9 8
10 8
Expected output: 2
Actual output: 0

// ans is total number of edges removed and al is adjacency list of the tree.
int dfs(int node)
{
visit[node]=true;
int num_vertex=0;
for(int i=0;i<al[node].size();i++)
{
if(!visit[al[node][i]])
{
int num_nodes=dfs(al[node][i]);
if(num_nodes%2==0)
ans++;
else
num_vertex+=num_nodes;
}
}
return num_vertex+1;
}

There is a typo. The condition expression in if clause
if (visited[i] == 0 && gph[i][j] == 1)
should be
if (visited[j] == 0 && gph[i][j] == 1)
BTW, the constraints in hackrank question is 2 <= n <= 100, so you definitely don't need a fixed array of size 201.

Related

Cant get my list to print out correctly with commas

I'm trying to get my program to find if a number is prime if it isn't then list out what the number is divisible by
#include <stdio.h>
int main()
{
int n, i, j, k = 0, c = 0;
printf("Enter an integer between 1 and 1000 (inclusive): \n");
scanf("%d", &n);
if (n > 1000 || n < 0) {
printf("You must enter a number between 1 and 1000 (inclusive).\n");
}
else
{
for (i = 1; i <= n; i++)
{
if (n % i == 0) // check divisible number from 1 to n
{
c++; // count the divisible numbers
}
}
if (c == 2) // c is 2 the number is prime
printf("%d is prime.", n);
else
{
printf("%d is divisible by ", n);
for (i = 2; i <= 31; i++) // first 11 prime numbers
{
k = 0;
for (j = 1; j <= i; j++)
{
if (i % j == 0) //i=(2,3,7,11,13,17,19,23,31)
{
k++;
}
}
if (k == 2)
{
if (n % i == 0) //if i prime number. n is divisible by i or not
printf("%d", i);
if (i < 5)
{
printf(", ");
}
}
}
printf(".");
printf("\n%d is not prime.\n", n);
}
}
return 0;
}
Currently, when I enter 62 it outputs
62 is divisible by 2, , 31.
But when I attempt to change the if(i < 3) statement than it'll mess with other printings such as trying with 468 it'll print out
468 is divisible by 2, 313.
the following proposed code:
cleanly compiles
does not check for I/O errors
performs the desired functionality
makes use of the Variable Length Arrays feature of C
and now, the proposed code:
#include <stdio.h>
int main()
{
int n, c = 0;
do {
printf("Enter an integer between 1 and 1000 (inclusive): \n");
scanf("%d", &n);
} while( n > 1000 || n < 0 );
int divisors[n];
divisors[ 0 ] = 0;
divisors[ 1 ] = 0;
for ( int i = 2; i < n; i++)
{
if (n % i == 0)
{
divisors[ i ] = i;
c++; // count the divisible numbers
}
else
divisors[ i ] = 0;
}
if ( !c )
printf("%d is prime.", n);
else
{
printf("%d is divisible by ", n);
for( int i = 0; i < n; i++ )
{
if( divisors[i] )
{
printf( "%d ", i );
}
}
printf(".");
printf("\n%d is not prime.\n", n);
}
return 0;
}
The following runs are with the values supplied by the OP
Enter an integer between 1 and 1000 (inclusive):
62
62 is divisible by 2 31 .
62 is not prime.
Enter an integer between 1 and 1000 (inclusive):
468
468 is divisible by 2 3 4 6 9 12 13 18 26 36 39 52 78 117 156 234 .
468 is not prime.
The posted code, first tests the given number against each number up to itself, counting the number of divisors, only to determine if it's prime. If it's not, then it somehow (with a lot of magic numbers) recalculates those factors and tries to print them as requested.
It would be easier to calculate the primes (once) and the list of factors first, storing them in some arrays and only then generate the desired output.
You can produce the same output while calculating each factor by keeping at least track of the number of factors already printed, if any.
In that case, I'd change the algorithm into something like this
// The orignal number will be consumed, divided by all of its factor.
int m = n;
int count = 0;
// Start from 2, the first prime, up to the last number less or equal to the sqrt(m).
for (int i = 2; i <= m / i; ++i)
{
// Check if what is left of the original number is divisible.
if ( m % i == 0 )
{
// Cunsume the number. E.g: 81 % 3 == 0 => 81 -> 27 -> 3 -> 1
// 24 % 2 == 0 => 24 -> 12 -> 6 -> 3
do
{
m /= i;
}
while ( m != 1 && m % i == 0 );
// Here, we can add the print logic and update the count of divisors
if ( count == 0 )
{
printf("%d is divisible by %d", n, i); // <- First factor
}
else
{
printf(", %d", i); // <- I-th factor
}
++count;
}
}
if ( count == 0 )
{
printf("%d is prime.\n", n);
}
else
{
if ( m != 1 )
{
printf(", %d.\n", m); // <- Last prime factor
}
puts(". It's not prime."); // 'printf(".\n%d It's not prime.\n", n);' if you prefer
}
Testable here.
The way of printing was the problem. It found 2 and printed out 2,. It found 3 and printed out 3, then it found 13 as the last divisor. From this you got 2, 313 as output.
I modified the part when the number is not a prime:
int first_divisor = 1;
printf("%d is divisible by ", n);
for (i = 2; i <= 31; i++) // first 11 prime numbers
{
k = 0;
for (j = 1; j <= i; j++)
{
if (i % j == 0) //i=(2,3,7,11,13,17,19,23,31)
{
k++;
}
}
if ((k == 2) && (n % i == 0))
{
if (first_divisor == 0)
{
printf(", ");
}
printf("%d", i);
first_divisor = 0;
}
}
printf(".");
printf("\n%d is not prime.\n", n);

Defective Binary search in C

Currently, I have a program the implements insertion sort and then uses binary search to search it (an array of ints). I currently have a 1 off error it seems.
My insertion sort should sort in descending order. Right now, it seems as if the value stored in the last position is missing.
#include <stdio.h>
void insertionSort(int nums[], int size)
{
int i, key, j;
for (i = 1; i < size; i++)
{
key = nums[i];
j = i - 1;
/* Move elements of arr[0..i-1], that are
greater than key, to one position ahead
of their current position */
while (j >= 0 && nums[j] > key)
{
nums[j + 1] = nums[j];
j = j - 1;
}
nums[j + 1] = key;
}
}
int binarySearch(int nums[], int size, int searchVal)
{
int l = 0, r = size - 1;
while (l <= r)
{
int m = l + (r - l) / 2;
// Check if x is present at mid
if (nums[m] == searchVal)
return m;
// If x greater, ignore left half
if (nums[m] < searchVal)
l = m + 1;
// If x is smaller, ignore right half
else
r = m - 1;
}
// if we reach here, then element was
// not present
return -1;
}
int main()
{
int n;
printf("Enter the number of elements (between 1 and 50) in the array: \n");
scanf("%d", &n);
int i, nums[n];
printf("Enter %d positive integers: \n", n);
for (i = 0; i < n; i++)
{
scanf("%d", &nums[i]);
}
int x = 0;
insertionSort(nums, n);
printf("Enter a positive integer or -1 to quit: \n");
scanf("%d", &x);
do
{
int ind = binarySearch(nums, n, x);
if (ind > 0)
{
printf("Found\n");
}
else
{
printf("Not Found\n");
}
printf("Enter a positive integer or -1 to quit: \n");
scanf("%d", &x);
} while (x != -1);
return 0;
}
Results:
Enter the number of elements (between 1 and 50) in the array:
9
Enter 9 positive integers:
7
4
10
49
6
12
32
17
Enter a positive integer or -1 to quit:
4
Not Found
Enter an positive integer -1 or to quit
12
Found
Enter a positive integer or -1 to quit:
5
Not Found
Enter a positive integer or -1 to quit:
49
Found
Enter a positive integer or -1 to quit:
-1
As you can see everything works but the first test where I test for the number 4. Does anyone know why I'm off by 1?
#include <stdio.h>
void insertionSort (int nums[], int size)
{
int i, key, j;
for (i = 1; i < size; i++) {
key = nums[i];
j = i - 1;
/* Move elements of arr[0..i-1], that are
greater than key, to one position ahead
of their current position */
while (j >= 0 && nums[j] > key) {
nums[j + 1] = nums[j];
j = j - 1;
}
nums[j + 1] = key;
}
}
int binarySearch (int nums[], int size, int searchVal)
{
int l = 0, r = size - 1;
while (l <= r) {
int m = l + (r - l) / 2;
// Check if x is present at mid
if (nums[m] == searchVal)
return m;
// If x greater, ignore left half
if (nums[m] < searchVal)
l = m + 1;
// If x is smaller, ignore right half
else
r = m - 1;
}
// if we reach here, then element was
// not present
return -1;
}
int main ()
{
int n;
printf
("Enter the number of elements (between 1 and 50) in the array: \n");
scanf ("%d", &n);
int i, nums[n];
printf ("Enter %d positive integers: \n", n);
for (i = 0; i < n; i++) {
scanf ("%d", &nums[i]);
}
int x = 0;
insertionSort (nums, n);
printf ("Enter a positive integer or -1 to quit: \n");
scanf ("%d", &x);
do {
int ind = binarySearch (nums, n, x);
if (ind >= 0) {
printf ("Found\n");
} else {
printf ("Not Found\n");
}
printf ("Enter a positive integer or -1 to quit: \n");
scanf ("%d", &x);
} while (x != -1);
return 0;
}
Try this one
just one error that is solve- if(ind>=0)
While you have discovered that checking the (ind > 0) causes failure to find the elements at index 0 and (ind >= 0) provides a solution, let's look at a short test case that validates the binarySearch() finds all elements of your sorted array without the user having to continually enter or redirect information to your program.
Any time you are testing algorithms, provides a simple validation framework that tests all elements, numbers, etc. without a user input requirement. Take your '9' numbers for example. Simply including an initialized array and sorting and then looping over all values will validate whether the binarySearch() is performing as intended. (it will save you no end of grief in the process as well). A short code exercising your search over the complete array can be as simple as:
int main (void) {
int nums[] = { 7, 4, 10, 49, 6, 12, 32, 17, 21 },
n = sizeof nums / sizeof *nums;
insertionSort (nums, n);
for (int i = 0; i < n; i++)
printf (" %2d (%s)\n", nums[i],
binarySearch (nums, n, nums[i]) >= 0 ? "found" : "not found");
}
Example Use/Output
$ ./bin/bsearchtest
4 (found)
6 (found)
7 (found)
10 (found)
12 (found)
17 (found)
21 (found)
32 (found)
49 (found)
Each element is now listed as "found" or "not found" and the code exits on its own.

Fill 2d array in spiral order in c

I'm doing program where I enter the number from keyboard. Then 2d array is created, and it's filled in spiral order till this number. All elements after the number will be equal to 0; The function fills the array in spiral order (to right -> down -> left -> up).
Code is:
#include <stdio.h>
#include <time.h>
void spiral(int array[100][100], int m, int n, int s)
{
int size, b, x = 0, y = 1, num = 1;
size = m*n;
for (num=1;num<=size+1;num++)
{
for (b = x; b < n; b++)
{
if (num <=s) {
array[x][b] = num;
num++;
}
else array[x][b] = 0;
}
if (num == size + 1)
{
break;
}
for (b = y; b < m; b++)
{
if (num <=s) {
array[b][n - 1] = num;
num++;
}
else array[b][n - 1] = 0;
}
if (num == size + 1)
{
break;
}
y++;
n--;
for (b = n - 1; b > x; b--)
{
if (num <= s) {
array[m - 1][b] = num;
num++;
}
else array[m - 1][b] = 0;
}
if (num == size + 1)
{
break;
}
for (b = m - 1; b > x; b--)
{
if (num <= s) {
array[b][x] = num;
num++;
}
else array[b][x] = 0;
}
x++;
m--;
}
}
int main()
{
int m, n, s, array[100][100];
srand(time(NULL));
//m=3;
// n=4;
m = 2 + rand() % 5;
n = 2 + rand() % 5;
//memset(array, 0, sizeof(array[0][0]) * 10 * 10);
printf("enter the number \n");
scanf("%i", &s);
spiral(array, m, n, s);
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
printf("%i\t", array[i][j]);
}
printf("\n");
}
return (0); }
However it doesn't work always correctly.
For example when i enter 15 and the program generates 4*3 array the output is`
1 2 3
10 12 4
9 -858993460 5
8 7 6`
However expected output is
1 2 3
10 11 4
9 12 5
8 7 6
Or when i enter 15 and the program generates 4*5 array the output is
1 2 3 4 5
14 0 0 0 6
13 0 0 0 7
12 11 10 9 8
And the expected output is
1 2 3 4 5
14 15 0 0 6
13 0 0 0 7
12 11 10 9 8
I can't find whats wrong with this code.
Try this:
void printArray(int array[10][10], int m, int n) {
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
printf("%i\t", array[i][j]);
}
printf("\n");
}
printf("\n");
}
void spiral(int array[10][10], int m, int n, int s)
{
int size, b, x = 0, y = 1, num = 1;
size = m*n;
while ( num <= s )
{
for (b = x; b < n; b++)
{
if (num <= s) {
array[x][b] = num;
num++;
} else array[x][b] = 0;
}
if (num == size + 1)
{
break;
}
for (b = y; b < m; b++)
{
if (num <= s) {
array[b][n - 1] = num;
num++;
} else array[b][n - 1] = 0;
}
if (num == size + 1)
{
break;
}
y++;
n--;
for (b = n - 1; b > x; b--)
{
if (num <= s) {
array[m - 1][b] = num;
num++;
} else array[m - 1][b] = 0;
}
if (num == size + 1)
{
break;
}
for (b = m - 1; b > x; b--)
{
if (num <= s) {
array[b][x] = num;
num++;
} else array[b][x] = 0;
}
x++;
m--;
}
}
int main()
{
int m, n, s, array[10][10];
srand(time(NULL));
m = 2 + rand() % 5;
n = 2 + rand() % 5;
memset(array, 0, sizeof(array[0][0]) * 10* 10);
printf("enter the number \n");
scanf("%i", &s);
spiral(array, m, n, s);
printArray(array, m, n);
return (0);
}
Before you had some weird for loop on top of your spiral function. The num++ in it interfered with the fact that you already increased num by one and made it skip the number the next time it would write in the uppermost line.
I changed it to a while loop that runs until num>s and it seems to work for me now.
Note that I just added printArray for easier debugging.

“Fun with Rotation” - Codechef September Long Challenge

Whatz wrong with that answer?Plz help me
question is:
You are given an array A of N integers. You are to fulfill M queries. Each query has one of the following three types:
C d : Rotate the array A clockwise by d units.
A d : Rotate the array A anticlockwise by d units.
R d : Query for the value of the element, currently being the d-th in the array A.
Input
The first line contains two numbers - N and M respectively.
The next line contains N space separated Integers, denoting the array A.
Each of the following M lines contains a query in the one of the forms described above.
Output
For each query of type R output the answer on a separate line.
Constraints
1 ≤ N ≤ 100000
1 ≤ M ≤ 100000
1 ≤ d ≤ N, in all the queries
1 ≤ elements of A ≤ 1000000
The array A and the queries of the type R are 1-based.
Example
Input:
5 5
5 4 3 3 9
R 1
C 4
R 5
A 3
R 2
Output:
5
3
3
Solution:
#include<stdio.h>
//#include<iostream>
//using namespace std;
int a[100001];
int index=0,n;
void clock(int);
void ant_clock(int);
void display(int);
int main()
{
unsigned int i,m;
char x;
int y;
scanf("%d %d",&n,&m);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
while(m--)
{
scanf(" %c%d",&x,&y);
if(1 <= y <= n)
{
if(x=='R')
display(y);
else if(x=='A')
ant_clock(y);
else if(x=='C')
clock(y);
}
else
return 0;
}
return 0;
}
void display(int y)
{
int j=index,x=0;
while(1)
{
if(x==y-1)
break;
j++;
x++;
if(j==n)
j=0;
}
printf("%d",a[j]);
}
void ant_clock(int y)
{
int j;
for(j=0;j<y;j++)
{
index--;
if(index==-1)
index=n-1;
}
}
void clock(int y)
{
int j;
for(j=0;j<y;j++)
{
index++;
if(index==n)
index=0;
}
}
It seems to be a problem with the query indices being 1-based. And your code has unnecessary loops in it.
#include <stdio.h>
int arr[100000];
int main() {
int base = 0, size, i, m;
char x;
scanf("%d%d", &size, &m);
for (i = 0; i < size; i++)
scanf("%d", &arr[i]);
while (m-- > 0) {
scanf(" %c%d", &x, &i);
if (x == 'R') {
printf("%d\n", arr[(base + i - 1) % size]);
} else if (x == 'A') {
if ((base -= i) < 0)
base += size;
} else if (x == 'C') {
base = (base + i) % size;
}
}
return 0;
}

Sub Grouping algorithm

Recently, someone asked me to make a C program that "groups" (his words, not mine!) numbers into pairs.
Here's how it works.
First, the user inputs the maximum range:(let's say) 10
Now, user inputs a number: (let's say) 4.
Then, the program groups 4 and 5 together. (ie. n and n+1)
Next User Input: 8
The program groups 8 and 9 as well.
Now, this goes on.
Exceptions: If the user enters a number that has already been grouped, like 4,5,8 or 9. Then the group which it belongs to gets removed altogether. Also, the program invalidates inputs that require pairing with numbers that are already paired. Eg. If 4 and 5 are paired, 3 is not a valid input.
Also, entering the extremes (here, 1 and 10) is not allowed.
I made the above program in C, using Visual Studio 2013. I have provided the code below.
My questions are:
A) How could I have made my code considerably better?(Apart from initializing the array AFTER accepting the max input)
B) More importantly, can someone tell me what this algorithm is? Is this a standard problem? Does it have any real world application/implementation? Or is it just some random idea?
#include<stdio.h>
#inlcude<conio.h>
#define array_size 10
int group[array_size][2] = { 0 };
int n = 0, max=0, search = 0, max_mem = 0;
int tcount = 2;
void sort(int x[][2]);
void print_groups();
void test_print();
void main()
{
group[0][0] = 0;
group[0][1] = 1;
printf("Enter a number:");
scanf_s("%d", &max);
max_mem = (max/2)+1;
if (max_mem > array_size)
{
printf("Not enough memory assigned!");
return;
}
else
{
group[max_mem-1][0] = max;
}
print_groups();
test_print();
while (1)
{
printf("Enter a number:");
scanf_s("%d", &n);
if ((n <= 1) || (n >= max-1))
{
printf("Invalid entry!");
continue;
}
search = 0;
for (int i = 1; i < max_mem; i++)
{
for (int j = 0; ((j < 2)&&(search!=1)); j++)
{
if (n == group[i][j])
{
group[i][0] = 0;
group[i][1] = 0;
search = 1;
}
if (group[i][0]==n+1)
{
printf("Already group exists -> (%d,%d)", group[i][0], group[i][1]);
//getch();
search = 1;
}
}
}
if (search != 1)
{
group[1][0] = n;
group[1][1] = n + 1;
}
printf("\nSorting!\n");
sort(group);
//clrscr();
print_groups();
test_print();
}
}
void sort(int x[][2])
{
int i, j, t[1][2];
for (i = 1; i <= max_mem - 2; i++)
for (j = 2; j <= max_mem-1 - i; j++)
if (x[j - 1][0] >= x[j][0])
{
t[0][0] = x[j - 1][0];
x[j - 1][0] = x[j][0];
x[j][0] = t[0][0];
t[0][1] = x[j - 1][1];
x[j - 1][1] = x[j][1];
x[j][1] = t[0][1];
}
}
void print_groups()
{
printf("The group is:\n%d ", group[0][1]);
for (int i = 1; i < max_mem-1; i++)
{
if (group[i][0] != 0)
{
printf("(");
printf("%d,", group[i][0]);
printf("%d", group[i][1]);
printf(")");
}
}
printf(" %d.", group[max_mem - 1][0]);
printf("\n");
}
void test_print()
{
printf("Array Formation:\n");
for (int i = 0; i < array_size; i++)
{
printf(" %d,%d ", group[i][0], group[i][1]);
}
printf("\n");
}
Sounds like it's just some random idea. You can simplify your code by using a one-dimensional array, where each entry in the array is
0 for numbers not in a group
1 for the first number of a group
2 for the second number of a group
For example, if array[4] is 1 and array[5] is 2, then 4 and 5 are a group.
When the user enters a new number, it's easy to update the array. Here's an example in pseudo-code of how the array would be updated if the user enters the number 7
if (array[7] == 0 and array[8] == 0)
array[7] = 1, array[8] = 2
else if (array[7] == 0 and array[8] == 1)
input is invalid
else if (array[7] == 1)
array[7] = 0, array[8] = 0
else if (array[7] == 2)
array[6] = 0, array[7] = 0

Resources