Solving #1015 (Brush) in LightOJ - c

I am trying to solve the following problem.
Input
Input starts with an integer T (≤ 100), denoting the number of test cases.
Each case starts with a blank line. The next line contains an integer N (1 ≤ N ≤ 1000), means that there are N students. The next line will contain N integers separated by spaces which denote the dust unit for all students. The dust unit for any student will not contain more than two digits.
Output
For each case print the case number and the total required dust units.
Sample Input
+--------------+-------------------------+
| Sample Input | Output for Sample Input |
+--------------+-------------------------+
| 2 | Case 1: 16 |
| | Case 2: 100 |
| 3 | |
| 1 5 10 | |
| | |
| 2 | |
| 1 99 | |
+--------------+-------------------------+
Here is my code:
#include <stdio.h>
int main() {
int kase = 0;
int i = 0, j = 0;
do {
scanf("%d", &kase);
} while (kase > 100);
int group[kase];
int tdust[kase];
for (i = 1; i <= kase; i++) {
tdust[i] = 0;
printf("\n");
do {
scanf("%d", &group[i]);
} while (group[i] < 1 || group[i] > 1000);
int stdNumber[group[i]];
for (j = 1; j <= group[i]; j++) {
do {
scanf("%d", &stdNumber[j]);
} while (stdNumber[j] >= 100);
tdust[i] = tdust[i] + stdNumber[j];
}
}
for (i = 1; i <= kase; i++)
printf("\nCase %d: %d", i, tdust[i]);
}
When I submit my code, OnlineJudge says I've got the wrong answer. How can I fix it?

You are getting WA because your code exhibits UB(Undefined Behaviour). You assume that the valid indices for an array of length n where n is a natural number, starts from 1 and ends at n. That is wrong.For an array of length n(n is a natural number), Array indices start from 0 and end at n-1.
To fix it, change
for(i=1; i<=kase; i++)
To
for(i=0; i<kase; i++)
And similarly,do the same for all the other loops. Also change
printf("\nCase %d: %d",i,tdust[i]);
To
printf("\nCase %d: %d",i+1,tdust[i]);
So that you get the desired result.

Related

Why my table is not displayed if I do not put it [i]

I would like to know what the [i] is for, and why my table is not displayed if I do not put it in.
Thank you!
#include <stdio.h>
void affiche(int* tableau, int taille);
int main()
{
int tableau[5] = { 12,15,50,20 };
affiche(tableau, 4);
return 0;
}
void affiche(int *tableau,int taille)
{
int i;
for (i = 0; i < taille; i++)`
{
printf("%d\n", tableau[i]);
}
}
[i] is the C language syntax for array notation.
tableau is an array of 5 integers.
int tableau[5] = {12,15,50,20}
In memory tableau has 5 slots allocated to it due to the above declaration.
Slots 0 through 3 are your initialization values.
Slot 4 is uninitialized (though modern c compilers might set this value to null or zero (0).
tableau
+-----------------------+
index | 0 | 1 | 2 | 3 | 4 |
+-----------------------+
value | 12 | 15 | 50 | 20 | ? |
+-----------------------+
inside function affiche(...) this statement
printf("%d\n", tableau)
tries to print to console a single integer (%d) followed by a newline (\n)
But tableau is an array of 5 integers.
So you need the array index to select a specific integer individually like this:
printf("%d\n", tableau[0]) // output: 12
printf("%d\n", tableau[1]) // output: 15
printf("%d\n", tableau[2]) // output: 50
printf("%d\n", tableau[3]) // output: 20
printf("%d\n", tableau[4]) // output: unknown, possible exception
or by function call to affiche(tableau, 4); which ends at index 3
void affiche( int *tableau, int taille)
{
int i;
for( i = 0; i < taille; i++){
printf( "%d\n", tableau[i] );
}
}
Which outputs:
12
15
50
20

Running into an identifiable Segmentation Fault

Whenever I run my code I get a message: Segmentation fault: 11
My question is why this message is popping up. I have done some research prior to this and have tried to fix it but I still have the same message pop up. Please review my code!
To give some context to my code: The goal of this program is to implement the Connect Four game between a computer and a human player. Functions are to be implemented in the file connect4_functions.c. Forward declarations of these functions are in the file connect4_functions.h. connect4.c contains the main () functions.
The code (connect4_functions.c) is below:
#include "connect4_functions.h"
int print_welcome(void) // PROBLEM: returnerer alltid 1
{
printf ("*** Welcome to the Connect Four game!!! ***\n");
printf ("Would you like to make the first move [y/n]: ");
if (getchar() == 'N' || getchar() == 'n') return 2;
else return 1;
while (getchar()!= '\n');
}
void display_board(int board[][BOARD_SIZE_VERT])
{
int i, j;
for (i = BOARD_SIZE_VERT-1; i >= 0; i--)
{
for (j = 0; j < BOARD_SIZE_HORIZ; j++) printf ("+---");
printf ("+\n");
for (j = 0; j < BOARD_SIZE_HORIZ; j++)
{
switch (board[j][i])
{
case 0: printf ("| "); break;
case 1: printf ("| O "); break;
case 2: printf ("| X "); break;
}
}
printf ("|\n");
} // end for
for (j = 0; j < BOARD_SIZE_HORIZ; j++) printf ("+---");
printf ("+\n");
for (j = 1; j <= BOARD_SIZE_HORIZ; j++) printf (" %d ", j);
printf ("\n");
} //end function display_board
int random_move(int board[][BOARD_SIZE_VERT], int computer_num)
{
int m = (rand() % BOARD_SIZE_HORIZ) + 1;
if (!is_column_full(board,m))
{
update_board(board,m,computer_num);
return m;
}
else return random_move(board,computer_num);
}
int player_move(int board[][BOARD_SIZE_VERT], int player_num)
{
int m;
printf ("Please enter your move: ");
scanf ("%d", &m);
while (getchar() != '\n');
if ( 0 > m || m > BOARD_SIZE_HORIZ)
{
printf ("Not a valid move. Enter a column number!\n");
return player_move(board, player_num);
}
if (is_column_full(board, m))
{
printf ("This column is full. Try again!\n");
return player_move(board, player_num);
}
update_board(board,m,player_num);
return m;
}
bool check_win_or_tie(int board[][BOARD_SIZE_VERT], int last_move)
{
int m, count = 0;
if (check_winner(board, last_move))
{
printf("Player %c won!\n", ( check_winner(board,last_move) == 1 ? '1' : '2' ) );
return true;
}
for (m = 0; m < BOARD_SIZE_HORIZ; m++) if ( is_column_full(board, m) ) count++;
if (count == BOARD_SIZE_HORIZ)
{
printf ("Tie game!\n");
return true;
}
else return false;
}
bool is_column_full(int board[][BOARD_SIZE_VERT], int m)
{
return (board[m-1][BOARD_SIZE_VERT-1]);
}
void update_board(int board[][BOARD_SIZE_VERT], int m, int player_num)
{
int i;
for ( i = 0; i < BOARD_SIZE_VERT ; i++)
{
if (!board[m-1][i])
{
board[m-1][i] = player_num;
return;
}
}
}
int check_winner(int board[][BOARD_SIZE_VERT], int last_move)
{
int i, row, count;
// Find row
for (row = 0; row < BOARD_SIZE_VERT; row++)
{
if (board[last_move-1][row]) count++;
}
row = count;
printf ("row = %d\n", row);
// Vertical
for (i = 0; i < BOARD_SIZE_VERT; i++)
{
if (board[last_move-1][i] == board[last_move-1][row]) count++;
else count = 0;
if (count == 4) return board[last_move-1][row];
else return 0;
}
count = 0; // reset
// Horizontal
for (i = 0; i < BOARD_SIZE_HORIZ; i++)
{
if (board[i][row] == board[last_move-1][row]) count++;
else count = 0;
if (count == 4) return board[last_move-1][row];
else return 0;
}
count = 0; // reset
return 0;
}
The code for connect4_functions.h (cannot be changed) is below:
#ifndef CONNECT4_FUNCTIONS
#define CONNECT4_FUNCTIONS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#define BOARD_SIZE_HORIZ 7
#define BOARD_SIZE_VERT 6
int print_welcome(void);
void display_board(int board[][BOARD_SIZE_VERT]);
int random_move(int board[][BOARD_SIZE_VERT], int computer_num);
int player_move(int board[][BOARD_SIZE_VERT], int player_num);
bool check_win_or_tie(int board[][BOARD_SIZE_VERT], int last_move);
bool is_column_full(int board[][BOARD_SIZE_VERT], int m);
void update_board(int board[][BOARD_SIZE_VERT], int m, int player_num);
int check_winner(int board[][BOARD_SIZE_VERT], int last_move);
int best_move(int board[][BOARD_SIZE_VERT], int computer_num);
#endif
The code for connect4.c (also cannot be changed) is below:
#include "connect4_functions.h"
int main()
{
int board[BOARD_SIZE_HORIZ][BOARD_SIZE_VERT] = { {0} };
int player_num, computer_num;
int last_move;
/* Ask Alice if she wants to go first */
player_num = print_welcome();
if (player_num == 1) computer_num = 2;
else computer_num = 1;
/* If Alice wants to go first, let her make a move */
if (player_num == 1)
{
display_board(board);
last_move = player_move(board,player_num);
display_board(board);
}
/* The main loop */
while (1)
{
/* Make a computer move, then display the board */
last_move = random_move(board,computer_num);
printf("Computer moved in column: %d\n", last_move);
display_board(board);
/* Check whether the computer has won */
if (check_win_or_tie(board,last_move)) return 0;
/* Let Alice make a move, then display the board */
last_move = player_move(board,player_num);
display_board(board);
/* Check whether Alice has won */
if (check_win_or_tie(board,last_move)) return 0;
} /* end of while (1) */
} /* end of main() */
Also, if you would like to see the original pdf it is linked below:
Link to pdf
The output is:
*** Welcome to the Connect Four game!!! ***
Would you like to make the first move [y/n]: y
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
1 2 3 4 5 6 7
Please enter your move: 4
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | O | | | |
+---+---+---+---+---+---+---+
1 2 3 4 5 6 7
Computer moved in column: 1
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| X | | | O | | | |
+---+---+---+---+---+---+---+
1 2 3 4 5 6 7
row = -355898527
Segmentation fault: 11
(If you have any questions about the context or purpose please don't hesitate to ask!)
Not having actually run the code, I believe the issue may be that count is not initialized in check_winner:
int check_winner(int board[][BOARD_SIZE_VERT], int last_move)
{
int i, row, count;
// Find row
for (row = 0; row < BOARD_SIZE_VERT; row++)
{
if (board[last_move-1][row]) count++;
}
row = count;
// WHAT IF IT EXITS THE for () WITHOUT board[last_move-1][row] being non-zero?
// HINT: count can be anything!
printf ("row = %d\n", row);
You then use row as an access into an array, and boom! You've accessed memory outside your permissions.
In the check_winner function you don't initialise the variable count. I get an unitialised variable runtime error, yet if I continue ahead a couple of lines later you then set:
row = count;
Which in my case is setting row to -858993459;
A couple of lines down in that same function you write:
if (board[last_move - 1][i] == board[last_move - 1][row]) count++;
// You use "row", an initialised variable as the index
// for the second subscript operator of board.
And that's where I get:
Access violation reading location 0x0000005663E82BB4. occurred
I think there should have been a warning shown about this unitialised variable. And honestly, I don't know if that's all that's wrong with it, but it looks like a pretty good game.
First of all, to be able to solve your problem, you should make sure everything that might be printed before the crash, has been printed. In this goal, you should add a fflush(stdout); instruction after each of your printing instructions
secondly, if this doesn't make clear at what place you program crashes, you should add supplementary tracing instruction inside the piece of code where it happens.
And then, when you have identified which instruction causes de crash, you should print it's variables to check if their values are what you expect.
Alternatively, you can use the assert instruction to make sure the variable values are all in the expected ranges.

Why the first prime number always becoming 1 instead of 2

Here i am trying to implement sieve of erastosthene in c.The program works fine except one major problem.I manually set the first prime number to be of value 2.But at the end when i loop through all the prime numbers array and print them ,the first value becomes 1 instead of 2.Can't figure out why this problem arises.Any help would be much appreciated.
#include<stdio.h>
#include<math.h>
int main(){
int n = 64;
int i,j,limit=sqrt(n)+2,nPrime=0;
int prime[50]={0},mark[64]={0};
mark[1]=1;
prime[nPrime++] = 2;
printf("%d\n",prime[0]); // initialized to 2
for(i=4;i<=n;i=i+2){
mark[i] = 1;
}
for(i=3;i<=n;i=i+2){
if(!mark[i]){
prime[nPrime++] = i;
if(i<=limit){
for(j=i*i;j<=n;j=j+i*2){
mark[j]=1;
}
}
}
}
int k;
int size = sizeof(prime)/sizeof(prime[0]);
printf("%d\n",prime[0]); // changed to 1;
for(k=0;k<size && prime[k]!=0;k++){
printf("%d ",prime[k]);
}
}
The problem is in this loop:
for(i=4;i<=n;i=i+2) {
mark[i] = 1;
}
The condition should be i < n, because with <= it will take the value 64, and that would be out of bounds.
When you set mark[64] = 1 you are modifying memory that does not belong to the mark array, in this case it turn out to be the first element of the prime array. If you test out other indexes, you could end up getting a segfault.
If you set manually mark[64] = 56, you will see that prime[0] == 56
Because local variable are declared on stack, in your case the variable mark[64] which is an array of 64 integer (64 * 4 = 256 bytes) occupies the first 256 bytes of the stack then the array prime (50 * 4 = 200 bytes) occupies the next 200 bytes as shown below:
Stack
|-----------|
| other |
| variables |
| |
prime[49]->|-----------| addr = 0x000001C8
| |
| prime |
|(200 bytes)|
prime[0]->| |
mark[63]->|-----------| addr = 0x00000100
| |
| |
| mark |
|(256 bytes)|
| |
mark[0]->|-----------| addr = 0x00000000
When you write mark[64] = 1, you are actually writing the four bytes of prime[0] = 1.

How to find Square of a number inside a Factorial while loop in C?

I'm trying to create a program that not only calculate the factorial of a number but also display an output where the factorial is less than the square of that number.
These are the requirements:
You type in a number between 3 to 9.
It displays in output both its factorial and its square.
If the factorial of the number inserted is less than the square of the number, Output the string "Gotcha!"
This is my code so far. Thank you
#pragma once
#include <stdio.h>
#define MIN 3
#define MAX 9
#define _CRT_SECURE_NO_WARNINGS
int main()
{
int i, fact = 1, num;
printf("Enter a number:\n");
scanf_s("%d", &num);
while (num >= MIN || num <= MAX)
{
for (i = 1; i <= num; i++)
{
fact = fact*i;
}
if (num < MIN || num > MAX)
{
printf("Out of range. Please try again.\n");
scanf_s("%d", &num);
}
else
{
printf("Factorial of %d is: %d\n", num, fact);
return 0;
}
}
}
Just calculate the square of the number by multiplying it by itself.
square = num * num;
printf("Square of %d is: %d\n", num, square);
if (fact < square)
printf("Gotcha!\n");
r.e. pragmatic approach, I agree with bodangly.
r.e. theory behind your question, lets dig into that a little...
edit: didn't look deeply enough, instead of never my answer should have been "mostly never (only twice for n=2 and n=3).
To recap your question:
Given 'n' find out if the "factorial of n" is less than the "square of n".
We can summarize this as:
n! < n^2
Let's flip this around to make it easier to manipulate:
n! < n^2
n^2 > n!
n * n > n * (n-1) * (n-2) * .. * 1
If we divide each side by n, we get the following.
n > (n-1) * (n-2) * .. * 1
n > (n-1)!
So the question becomes: for what value(s) of n is n > (n-1)! ?
(spoiler alert: not very often)
Let's look to see when n > (n-1)!
Consider this table...
+------------+----+-----+----------+-------------------------+
| n > (n-1)! | n | n-1 | (n-1)! | notes... |
+------------+----+-----+----------+-------------------------+
| no | 0 | -1 | undef | (-1)! is undefined |
| no | 1 | 0 | 1 | 0! is 1 by definition |
| yes | 2 | 1 | 1 | 1! is 1 by definition |
| yes | 3 | 2 | 2 | ( or 2 * 1 ) |
| no | 4 | 3 | 6 | ( or 3 * 2 * 1 ) |
| no | 5 | 4 | 24 | ( or 4 * 3 * 2 * 1 ) |
+------------+----+-----+----------+-------------------------+
Which means n > (n-1)! is only true for n=2 and n=3.
Try something like this:
#include <stdio.h>
#define MIN 3
#define MAX 9
#define _CRT_SECURE_NO_WARNINGS
enum {NO_ERRORS, ERROR};
enum {FALSE, TRUE};
int main()
{
int i, fact = 1, num, valid = FALSE, sqr;
while(!valid){
printf("Enter a number:\n");
scanf("%d", &num);
if (num < MIN && num > MAX){
printf("Out of range. Please try again.\n");
}else{
valid = TRUE;
}
}
/* get the factorial */
for (i = 1; i < num; i++){
fact = fact * i;
}
/* get the square */
sqr = num * num;
/* output */
if( fact < sqr){
printf("%s\n", "Gotcha!");
}else{
printf("Factorial of %d is: %d\n", num, fact);
}
return NO_ERRORS;
}
Thanks

bubble sort ideone time limit exceeded

#include <stdio.h>
int main(void) {
int a[5]={1,2,0,5,4},i,j,c;
for(i=0;i<5;i++)
{
for(j=0;j<5-i;j++){
if(a[j]>a[j+1])
{
c=a[j];
a[j]=a[j+1];
a[j+1]=c;
}
}
}
for(i=0;i<5;i++)
{
printf("%d",a[i]);
}
return 0;
}
ideone says "Time limit exceeded time: 5 memory: 2048 signal:24"
but it works fine on turbo compiler
for(j=0;j<5-i;j++){
if(a[j]>a[j+1])
a[j+1] is array out of bound access which will lead to undefined behavior
Try this for bubble sort..Machine cycle will not be hampered in any compilers..
for (i = 0; i < count -1; i++)
for (j = 0; j < ((count - 1) - i); j++) {
if (memptr[j]>memptr[j+1]) {
temp = memptr[j];
memptr[j] = memptr[j + 1];
memptr[j + 1] = temp;
}
}
int a[5]={1,2,0,5,4}
So, for the following index you will get the following content:
index ->| 0 | 1 | 2 | 3 | 4 |
content ->| 1 | 2 | 0 | 5 | 4 |
Now In your outer loop for(i=0;i<5;i++), for the first iteration i = 0, then the inner loop breaking condition will be,
for(j=0;j<5-i;j++)
or,
for(j=0;j<5-0;j++)
Hence the value of j will increase 0 to 4.
Now think what will happen a[j+1], when j = 4!
You are trying to access, a[4+1] or, a[5] where the index of array a is defined up to 4.
So at a[5], you will get Undefined behavior.
Try:
for(j=0; j<5 -i -1; j++)

Resources