Halloween is round the corner and it's time for trick-or-treating. You reside at the top left corner of a n-by-n town map and heading to the halloween party located at the bottom right corner. While on your trip, you decide to visit a minimal number of houses to get treats. You have a map of town with information of the amount of treats (≥ 0) available at each location. As an example, the town map for n=3 is shown below.
6 8 2
4 5 1
3 9 10
To get the maximum treats, you will start from home (6), then head east to (8), then south to (5), then south to (9), then east to (10) and end up at the party.
So the number of treats is 6+8+5+9+10=38.
Notice that to visit a minimal number of houses, it necessitates that you either travel east or south from one house to the next until you arrive at the party. To obtain the maximum treats, track the current maximum as you visit each home.
6, 14, 2+14=16
10, 5+max(10,14)=19
3+10=13
So the program needs to be choosing the maximum value to add let's say for 10 and 14, i will choose to add 14. But I have trouble with this using for loops. Anyone can help?
1 #include <stdio.h>
2
3 #define SIZE 10
4
5 int pathmax(int map[][SIZE], int n);
6 void read(int map[][SIZE], int n);
7 int max(int x, int y);
8
9 int main(void)
10 {
11 int map[SIZE][SIZE], n;
12
13 printf("Enter n: ");
14 scanf("%d", &n);
15
16 read(map,n);
17
18 printf("Maximum: %d\n", pathmax(map,n));
19
20 return 0;
21 }
22
23 int max(int x, int y)
24 {
25 if (x > y)
26 return x;
27 else
28 return y;
29 }
30
31 int pathmax(int map[][SIZE], int n)
32 {
33 int k, i, j;
34
35 for (k = 1; k < 2*n-1; k++)
36 for (i = 0; i < n; i++)
37 for (j = 0; j < n; j++)
if(i+j==k)
{
if (i==0)
map[i][j] += map[i][j-1];
else if (j == 0)
map[i][j] += map[i-1][j];
else
map[i][j] += max(map[i-1][j], map[i][j-1];
}
}
Recursive solution, will teacher believe you wrote it?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAXTREAT 10
#define GRID 3
int map [GRID][GRID];
int maxtreats;
void explore(int x, int y, int treats)
{
treats += map [y][x];
if (x == GRID-1 && y == GRID-1) { // reached bottom right?
if (treats > maxtreats) // check result
maxtreats = treats; // finish recursion
} else { // recurse
if (x+1 < GRID)
explore (x+1, y, treats); // go east
if (y+1 < GRID)
explore (x, y+1, treats); // go south
}
}
int main()
{
int x, y;
srand ((unsigned int)time(NULL)); // seed random num gen
for (x=0; x<GRID; x++) { // set up random map
for (y=0; y<GRID; y++) {
map[y][x] = 1 + rand() % MAXTREAT;
printf ("%4d", map[y][x]);
}
printf ("\n");
}
explore (0, 0, 0);
printf ("Max treats %d\n", maxtreats);
return 0;
}
Related
I am learning c and encountered maximum cost path question in which
Rules:
matrix is n x n size
Starting from the cell (bottommost leftmost cell), you want to go to the topmost
rightmost cell in a sequence of steps. In each step, you can go either right or up from
your current location.
I tried to solve using dynamic programming and this is the function I have written
computecost(int *utr,int n)//utr is the input matrix
{
int *str;
int i,j;
str=(int *)malloc(n*n*sizeof(int));
for(j=0;j<n;j++)//intialization of bottom row
{
str[n*(n-1)+j]=utr[n*(n-1)+j];
}
for(i=n-2;i>=0;i--)
{
for(j=0;j<n;j++)
{
str[n*i+j]=utr[n*i+j]+max(str[n*(i+1)+j],str[n*(i+1)+(j+1)]);
}
}
printf("%d",str[n*0+0]);
return 0;
}
and this is the input
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&str[n*i+j]);
}
}
but
for the matrix 5 x5
1 4 8 2 9
32 67 18 42 1
4 86 12 7 1
8 4 12 17 44
1 43 11 45 2
the desired output is 272 but I am getting 211.
the output matrix for my case
1 43 11 45 2
51 47 57 62 46
55 143 74 69 47
175 210 92 111 52
211 214 119 113 64
Can anyone help me?
You don't need dynamic programming for this since there are no overlapping sub-problems. Just use a simple recursion.
const int n = 5;
int mat[n][n] = {
{1,4,8,2,9},
{32,67,18,42,1},
{4,86,12,7,1},
{8,4,12,17,44},
{1,43,11,45,2}
}; // input matrix
int f(int x, int y, int sum){
if(x == 0 && y == 4)
return sum;
int p = 0, q = 0;
if(x - 1 >= 0)
p = f(x-1, y, sum + mat[x-1][y]);
if(y + 1 <= 4)
q = f(x, y+1, sum+mat[x][y+1]);
return max(p,q);
}
int main(){
int maxSum = f(4,0, mat[4][0]);
printf("%d\n", maxSum);
}
You were not very far to succeed.
In practice, you did not initialize correctly the bottom row.
Moreover, there was a little mistake in the iteration calculation.
This is the corrected code.
As said in a comment, it could be further simplified, by avoiding the use of a new array, simply updating the input array.
#include <stdio.h>
#include <stdlib.h>
int max (int a, int b) {
return (a > b) ? a : b;
}
int computecost(int *utr,int n) { //utr is the input matrix
int *str;
str = malloc (n*n*sizeof(int));
str[n*n - 1] = utr[n*n - 1];
for (int j = n-2; j >= 0; j--) { //intialization of bottom row {
str[n*(n-1)+j] = utr[n*(n-1)+j] + str[n*(n-1)+j+1]; // corrected
}
for (int i=n-2; i>=0; i--) {
str[n*i+n-1] = utr[n*i+n-1] + str[n*(i+1)+n-1];
for(int j = n-2; j >= 0; j--) {
str[n*i+j] = utr[n*i+j] + max(str[n*(i+1)+j],str[n*i + j+1]); // corrected
}
}
int cost = str[0];
free (str);
return cost;
}
int main() {
int A[25] = {
1,43,11,45,2,
8,4,12,17,44,
4,86,12,7,1,
32,67,18,42,1,
1,4,8,2,9
};
int ans = computecost (A, 5);
printf ("%d\n", ans);
return 0;
}
I need to check if I can find inside of given matrix size of 5*8
a matrix that has a transpose and if there is more than one I must find the biggest one.
example of a given matrix
1 2 0 3 2 1 0 7
2 3 4 1 2 3 4 5
3 4 6 2 5 6 7 6
4 5 7 3 6 8 9 8
6 7 1 4 7 9 0 9
in this matrix we can find a matrix 4x4
that has transpose and its the biggest matrix in the main matrix
1 2 3 4
2 5 6 7
3 6 8 9
4 7 9 0
#include <stdio.h>
#define M 4
#define column 5
#define row 8
int main()
{
int matrixA[5][8];
printf("please enter a matrix to check if there is a transpose matrix\n");
for (int i = 0; i < column; i++)
{
for (int j = 0; j < row; j++)
{
printf("please enter %d row and %d column: ", i + 1, j + 1);
scanf("%d", &matrixA[i][j]);
}
}
transpose(matrixA, column, row);
}
void transpose(int A[][row], int c, int r)
{
int matrixAT[M][M];
for (int size = r; size > 0; size--)
{
for (int j = 0; j < c - size + 1; j++)
{
for (int b = 0; b <= r - size; b++)
{
printf("Checking Matrix at row: %d , column: %d ,size: %dx%d", j, b, size, size);
for (int k = j, w = 0; k < size + j; k++, w++)
{
for (int l = b, z = 0; l < size + b; l++, z++)
{
matrixAT[w][z] = A[k][l];
}
printf("/n");
}
if (IsSymmetric(matrixAT, size))
printf("Matrix found");
}
}
}
}
int IsSymmetric(int mat[M][M], int size)
{
int flag = 0;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
if (mat[i][j] == mat[j][i]) flag++;
}
}
return flag == size * size ? 1 : 0;
}
this is my code i dont know what im doing wrong
Your IsSymmetric is slow as it always check all elements why not stop on first inequality instead? Also copying it to temp array again and again ...
The main problem is You are not checking every position and size as you call transpose(matrixA, column, row); only once outside the loops ...
Also your main does not return anything and its declared as int ...
I would start with brute force like this:
#define column 5
#define row 8
int IsSymmetric(int mat[column][row], int i0,int j0,int size) // check n*n sub matrix at i0,j0 no need to copy again and again to temp array
{
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
if (mat[i0+i][j0+j] != mat[i0+j][j0+i]) return 0;
return 1;
}
int min(int a,int b){ return (a<b)?a:b; } // not sure if min is present in your environment if is comment this line out
int main()
{
int matrixA[5][8];
...
for (int i = 0; i < column; i++)
for (int j = 0; j < row; j++)
for (int n = 1; n <= min(column-i,row-j); n++)
if (IsSymmetric(matrixA,i,j,n))
{
// here do what you want with the i,j,n*n sub matrix
// like remember position and size for the biggest n
}
...
return 0; // return value as you declared int main
}
Hope I did not make any typo in here as I just wrote this into answer editor from your original code.
How ever as you can see its O(n^4) complexity (on average O(n^3)) which is really slow. However for your small matrix its not a problem.
In case you need something faster then we need to know more about the data ... for example what is the range of the values? Some hints:
on positive IsSymmetric test one cell bigger submatrix without testing the previous elements again (recursively increasing diagonal).
use histogram to detect values that might be only on diagonals (appear once globally or odd times locally)
Using the incremental symmetry test results in O(n^3) solution:
//---------------------------------------------------------------------------
#define column 5
#define row 8
//---------------------------------------------------------------------------
void submatrix_print(int mat[column][row], int i0,int j0,int n,int m)
{
int i,j;
printf("%i*%i at %i,%i\r\n",n,m,i0,j0);
for (i=0;i<n;i++,printf("\r\n"))
for (j=0;j<m;j++)
printf("%1i ",mat[i0+i][j0+j]);
}
//---------------------------------------------------------------------------
void submatrix_print_transposed(int mat[column][row], int i0,int j0,int n,int m)
{
int i,j;
printf("%i*%i at %i,%i\r\n",n,m,i0,j0);
for (i=0;i<m;i++,printf("\r\n"))
for (j=0;j<n;j++)
printf("%1i ",mat[i0+j][j0+i]);
}
//---------------------------------------------------------------------------
int min(int a,int b){ return (a<b)?a:b; }
int submatrix_symmetric(int mat[column][row], int i0,int j0) // returns biggest symetric submatrix size >=1 found at i0,j0
{
int i,n,N;
N=min(column-i0,row-j0); // max size that still fits into matrix
for (n=2;n<N;n++) // test all sizes above 1
for(i=0;i<n-1;i++) // only test newly added cells to last sub matrix
if (mat[i0+n-1][j0+i]!=mat[i0+i][j0+n-1])
return n-1; // first non match means last tested size i svalid
return n; // no mismatches mean full size is valid
}
//---------------------------------------------------------------------------
int main()
{
int mat[5][8]=
{
1,2,0,3,2,1,0,7,
2,3,4,1,2,3,4,5,
3,4,6,2,5,6,7,6,
4,5,7,3,6,8,9,8,
6,7,1,4,7,9,0,9,
};
submatrix_print(mat,0,0,5,8);
// submatrix_print_transposed(mat,0,0,5,8);
int i,j,n,i0=0,j0=0,n0=0;
for(i=0;i<column;i++)
for(j=0;j<row;j++)
{
n=submatrix_symmetric(mat,i,j);
if (n0<n){ n0=n; i0=i; j0=j; }
}
submatrix_print(mat,i0,j0,n0,n0);
return 0;
}
//-------------------------------------------------------------------------
The result of the code is:
5*8 at 0,0 // input matrix
1 2 0 3 2 1 0 7
2 3 4 1 2 3 4 5
3 4 6 2 5 6 7 6
4 5 7 3 6 8 9 8
6 7 1 4 7 9 0 9
4*4 at 1,3 // biggest symmetric sub matrix found
1 2 3 4
2 5 6 7
3 6 8 9
4 7 9 0
you can make a function that check if the matrix ican be transposed or no
and another function that take evry time a part from the main matrix and you move it everytime and check it with 1st function
example :
1st matrix :m[1][1] starting from zero
1 2
2 3
2 matrix :m[2][2] starting from one
2 0
3 4
then when you finish with 2 demension matrix you go to 3
till the end
i hope you understand me and sorry for my bad english
This question already has answers here:
Pascal's Triangle in C
(4 answers)
Closed 1 year ago.
I tried to code a program that will give the pascal triangle without using arrays and keeping in mind the formula that each element of the pascal triangle can be calculated as n choose k" and written like this:
n choose k = n! / k!(n-k)!
(for both n and k starting from 0)
so I also had to define the factorial function and it worked for the first 14 lines.
but in line 15 and more my numbers started to decrease and became also negative but I don't understand why this happened.
Here is the code:
#include <stdio.h>
int factorial(int a);
int main()
{
int row, j, i, space, tot;
scanf("%d", &row);
space=row;
for(i=0; i<row; i++)
{
for(space=0; space<row-i; space++)
{ printf(" "); }
for (j = 0; j <= i; j++)
{
if (j == 0 || i == 0)
{ tot=1; }
else
{
int n=factorial(i);
int k=factorial(j);
int z=factorial(i-j);
tot= n/(k*z);
}
printf("%6d", tot);
}
printf("\n");
}
}
int factorial(int a)
{
int fact=1;
for (int m=1; m<=a; m++)
{ fact*=m; }
return fact;
}
this is my output in line 15:
1 0 1 5 14 29 44 50 44 29 14 5 1 0 1
but the actual output should be this:
1 14 91 364 1001 2002 3003 3432 3003 2002 1001 364 91 14 1
I couldn't find the problem so I would be happy and thankful if anyone could help me.
If you don't care much about computation time then you could compute coefficient directly from their recursive definition.
int pascal(int x,int y) {
if (x==0 || y==0) return 1;
return pascal(x-1,y)+pascal(x,y-1);}
unfortunately... I asked about exactly this question yesterday about another error, hopefully, I don't have those errors anymore but I still have this awkward output, like some sort of numbers depending on the array element like -4221565 or -4647963, etc... Until now I think that my array appending part works correctly, I tried that. But I guess something wrong about the -1 in the condition but I can't name it. For loop is also another place I would say ok. I am trying to solve this since 3.00 AM then procrastinate it, then tried it... And the deadline is 7.04.2020(TODAY) 22.00 so I am starting to getting crazy. Any help would be appreciated.Thanks.So this is the question(İnputs does not have to be 15 it can be up to 15):
You have to transport a maximum of 15 different loads from one port to another. The carrying capacity of a cargo ship, which will transport those loads, is 50 tons. Loads are enumerated and the information about the weight of every load is given as input.
Suppose that the weight of every load is smaller than or equal to 50 tons and greater than 0.
You will read the weight of every load from the input in a single line. Your input will end with a -1. You will print the number of trips necessary.
Sample Input:
50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 -1
Output:15
Input:
20 25 25 36 37 25 20 10 50 9 16 45 32 10 25 -1
Output:
11
Input:
14 16 50 10 10 19 45 40 32 24 25 47 10 12 25 -1
Output:
9
Input:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 -1
Output:
3
Here is my code:
#include <stdio.h>
int main()
{ int w,i,sum,index;
int list[15];
w = 1;
index = 0;
do
{ scanf("%d",&w);
list[index] = w;
index++;
}while(w != -1);
sum = 0;
for(i = 0;i < 15;i++)
{
sum +=list[i];
}
sum = sum / 50;
printf("%d",sum);
return 0;
}
in your code you are passing boundaries of array -1 will be 16th element of array which wrong. you need at least int list[16];.
but your solution is wrong , you are divining loads to place them in cargo ship which judging by given input and output. for example if there are 30 and 10 in one ship you can't divide a 20 load to two 10 loads in order to place max of 50 ton in the ship.
what you need is :
consider a ship with 0 ton
add load to it while sum of load are lower or equal to 50
if with new load added sum of current ship goes upper than 50 counter_ship++ and then add that load to a new load.
int main(void) {
int w;
int sum = 0;
int ship_counter = 0;
scanf("%d", &w);
while (w != -1) {
if (sum + w > 50)
{
ship_counter++;
sum = 0;
}
sum += w;
scanf("%d", &w);
}
if (sum != 50)
ship_counter++;
printf("%d", ship_counter);
return 0;
}
You need to sort the array. Then you need to check against a threshold amount. If it surpasses that you add a container.
#include <stdio.h>
void swap(int* xp, int* yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
// Function to perform Selection Sort
void selectionSort(int arr[], int n)
{
int i, j, min_idx;
// One by one move boundary of unsorted subarray
for (i = 0; i < n - 2; i++) {
// Find the minimum element in unsorted array
min_idx = i;
for (j = i + 1; j < n-1; j++)
if (arr[j] < arr[min_idx])
min_idx = j;
// Swap the found minimum element
// with the first element
swap(&arr[min_idx], &arr[i]);
}
}
int main()
{ int w,i,sum,index;
int list[15];
w = 1;
index = 0;
do
{ scanf("%d",&w);
list[index] = w;
index++;
}while(w != -1);
selectionSort(list,index);
for (int i = 0; i < index; i++)
printf("%d ", list[i]);
printf("\n");
int ans=0;
int threshold=0;
for(int i=0; i<index; ++i){
if(threshold + list[i]<=50){
threshold+=list[i];
}
else {
threshold = list[i];
++ans;
}
}
ans++;
printf("%d", ans);
return 0;
}
Change the do-while loop to a while like this:
while(w != -1 && index < 15)
{ scanf("%d",&w);
list[index] = w;
index++;
}
This way you avoid writing beyond array's boundary.
Then, the condition of the for loop could be:
for(i = 0;i < index; i++)
(value of index comes from the previous loop, and it's only up to the next item of the last inserted).
So you 're summing up the items that actually had an input, not the whole array.
Of course you could do without an array, as others commented.
Hope that helps
Your code has several issues, and I didn´t felt well to improve what still got logical issues in it, so I do something I normally do not (because apparently you seem to be very stressed about that and you are in a hurry) and provide you my own version of how I did the task:
#include <stdio.h>
#define MAX_LOADS 15
#define MAX_CAP 50
int main()
{
int w[MAX_LOADS+1];
int trips = 0;
int i = 0;
int sum = 0;
int max = 0;
int loads = 0;
int rest = 0;
printf("Enter the Weights of the Loads:\n");
while(i < (MAX_LOADS + 1))
{
scanf(" %d",&w[i]);
printf(" ");
if(w[i] == -1)
{
break;
}
sum = sum + w[i];
loads++;
i++;
}
printf("\n");
printf("%d Loads have a weight of %d tons.\n", loads, sum);
if(sum <= MAX_CAP)
{
printf("The amount of needed trips are: 1");
}
else
{
for(int i = 0; i < loads; i++)
{
if(w[i] == MAX_CAP)
{
w[i] = 0;
trips++;
continue;
}
else if(w[i] < MAX_CAP && w[i] > 0)
{
rest = MAX_CAP - w[i];
w[i] = 0;
for(int j = 0; j < loads; j++)
{
if(i == j)
continue;
if(w[j] == rest)
{
w[j] = 0;
break;
}
else if(w[j] < rest && w[j] > 0)
{
rest = rest - w[j];
w[j] = 0;
}
if(rest == 0)
{
break;
}
}
trips++;
}
}
printf("The amount of needed trips are: %d", trips);
}
return 0;
}
Output / Execution 1:
Enter the Weights of the Loads:
10 20 40 -1
3 Loads have a weight of 70 tons.
The amount of needed trips are: 2
Output / Execution 2:
Enter the Weights of the Loads:
50 50 50 50 50 -1
5 Loads have a weight of 250 tons.
The amount of needed trips are: 5
Output / Execution 3:
Enter the Weights of the Loads:
10 10 10 10 10 -1
5 Loads have a weight of 50 tons.
The amount of needed trips are: 1
#include <stdio.h>
#define MAX_SIZE 15
int main()
{
/* Let's define variables here. */
int i=0,j=0 ;
int input;
int weights[MAX_SIZE];
int numberOfTrips = 0;
int sum = 0;
/* Inputs is taken here from usre, Max = 15 */
printf("Input:\n");
scanf("%d",&input);
while(input != -1){
if (i< MAX_SIZE){
if (input <= 50 && input>= 0){
weights[i] = input;
i = i +1;
} else printf("Wrong Input! \nPlease Enter value between 0 and 50\n");
}
else printf("You reach MAX_SIZE, please Enter -1 to see the Output");
scanf("%d",&input);
}
printf("\n");
/* We are going will count the number of trips necessary*/
if(input == -1){
if (weights[0] != 0){
/* Let's test the first value*/
numberOfTrips = numberOfTrips +1;
}
sum= weights[0];
for (j = 1; j<i; ++j){
sum = sum +weights[j];
if (sum>50){
numberOfTrips = numberOfTrips +1;
sum = weights[j];
}
}
}
/*Finally, let's print the output here.*/
printf("Output:\n");
printf("%d",numberOfTrips);
return 0;
}
I'm developing a system that can explore entirely a simple heuristic map of this gender (which can have different numbers of branches, and different depths) :
Simple heuristic map
So, I'm saving the positions explored in an int array of the size of the depth of the map. The goal is to explore all nodes of the map, so to have this output : 0 2 6, 0 2 7, 0 3 8, 0 3 9, 1 4 10 etc.. But actually with my code (which needs to be called several times because it can update just one time the array), i have this : 0 2 6, 0 2 7, 0 3 8, **1** 3 9, 1 4 10 etc..
This is my code, I don't know how to solve this problem..
void get_next_branch(int *s, int nbr_branch, int size)
{
int a;
a = 0;
while (a < size)
{
condition = (size - a)/(nbr_branch - 1);
if (condition)
{
if (s[size - 1] % (condition) + 1 == condition)
s[a]++;
}
a++;
}
}
And this is the main example who call this function.
int main(void)
{
int id[3] = {0, 2, 6};
while (id[2] < 13)
{
printf("%d %d %d\n", id[0], id[1], id[2]);
get_next_branch(id, 2, 3);
}
return (0);
}
I thank you in advance!
You might want to use a closed formula for this problem
b being the number of branches
d the depth you want to find the numbers in (d >= 0)
we get immediately
Number of nodes at depth d = bd+1
(since at depth 0 we have already two nodes, there is no "root" node used).
The number of the first node at depth d is the sum of the number of nodes of the lower levels. Basically,
first node number at depth 0 = 0
first node number at depth d > 0 = b1 + b2 + b3 + ... + bd
This is the sum of a geometric series having a ratio of b. Thanks to the formula (Wolfram)
first node number at depth d = b * (1 - bd) / (1 - b)
E.g. with b == 2 and d == 2 (3rd level)
Number of nodes: 2 ^ 3 = 8
Starting at number: 2 * (1 - 2^2) / (1 - 2) = 6
A program to show the tree at any level can be done from the formulas above.
To print a number of levels of a tree with b branches:
Utility power function
int power(int n, int e) {
if (e < 1) return 1;
int p=n;
while (--e) p *= n;
return p;
}
The two formulas above
int nodes_at_depth(int branches, int depth) {
return power(branches, depth+1);
}
int first_at_depth(int branches, int depth) {
return (branches * (1 - power(branches, depth))) / (1 - branches);
}
Sample main program, to be called
./heuristic nb_of_branches nb_of_levels
that calls the two functions
int main(int argc, char **argv)
{
if (argc != 3) return 1;
int b = atoi(*++argv);
int d = atoi(*++argv);
if (b < 2) return 2;
int i,j;
for (i=0 ; i<d ; i++) {
int n = nodes_at_depth(b, i); // number of nodes at level i
int s = first_at_depth(b, i); // first number at that level
for (j=0 ; j<n ; j++) printf(" %d", s+j);
printf("\n");
}
return 0;
}
Calling
./heuristic 2 4
gives
0 1
2 3 4 5
6 7 8 9 10 11 12 13
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29