Here's the problem https://www.hackerrank.com/challenges/extra-long-factorials
Here's my code
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
int product[200];
for (int i = 0; i < 200; i++)product[i] = 0;
product[0] = 1;
for (int i = 1; i <= n; i++){
int a[200], res[200];
for (int j = 0; j < 200; j++)a[j] = 0, res[j] = 0;
int n = i;
int k = 0;
while(n != 0){
a[k] = n % 10;
n = n / 10;
k++;
}
int at[200][200];
for (int p = 0; p < 200; p++){
for (int h = 0; h < 200; h++){
at[p][h] = 0;
}
}
int carry = 0;
for (int x = 0; x < 200; x++){
for (int d = 0; d < 200; d++){
at[x][x+d] = ((product[d] * a[x]) % 10) + carry;
carry = (product[x] * a[d]) / 10;
}
}
int carry2, temp;
for (int u = 0; u < 200; u++){
temp = 0;
for (int e = 0; e < 200; e++){
temp += at[e][u];
}
temp = (temp + carry2);
carry2 = temp/10;
res[u] = temp %10;
product[u] = res[u];
}
}
int f = 0;
for (; f < 200; f++){
if(product[200-f-1] != 0)break;
}
for (; f < 200; f++){
cout << product[200-f-1];
}
return 0;
}
It runs fine on gcc on my mac and gives a correct answer. However it gives a runtime error on the online judge as well as ideone.
I've debugged the code and the error is caused by cin >> n; It runs fine without it and gives a correct answer (which is 1). The test input that caused the error is 25 so it's not a big number. I dont know exactly what's the problem or how is it causing the error. Thank you.
This is the problem:
at[x][x+d] = ...
because both x and d run from 0 to 200, but at is an array on the stack, with size: [200][200] so obviously x+d will overwrite the code coming after the array declaration.
This is a classical buffer overflow :)
(Obviously, initializing carry2 won't hurt either, but not doing that will not give the core dump at 0x0, just some unexpected behaviour)
Related
I have written this counting sort algorithm, but am not sure why it isn't working... Could anyone check and give me a few pointers on what to fix? Thanks!
#include <iostream>
using namespace std;
int main(){
int arr[10] = {1434, 1415, 1217, 4218, 3618, 176, 1021, 3785, 1891, 1522};
int C[4219];
for (int i = 0; i < 4219; ++i) {
C[i] = 0;
}
for (int j = 0; j < 10; ++j) {
C[arr[j]] = C[arr[j]] + 1;
}
for (int k = 10; k > 0; --k) {
C[k] = C[k] + C[k + 1];
}
int B[10];
for (int l = 0; l < 10; ++l) {
B[C[arr[l]] - 1] = arr[l];
C[arr[l]] = C[arr[l]] - 1;
}
for (int m = 0; m < 10; ++m) {
cout << B[m] << " ";
}
return 0;
}
The problem is in the third loop. You iterate only through 10 elements of the array C.
You had created small mistake in the code.....
#include <iostream>
using namespace std;
int main(){
int arr[10] = {1434, 1415, 1217, 4218, 3618, 176, 1021, 3785, 1891, 1522};
int C[4219];
for (int i = 0; i < 4219; ++i) {
C[i] = 0;
}
for (int j = 0; j < 10; ++j) {
C[arr[j]] = C[arr[j]] + 1;
}
for (int k = 1; k < 4219; ++k) { // mistake
C[k] = C[k] + C[k - 1];
}
int B[10];
for (int l = 9; l >=0; --l) { // suggestion
B[C[arr[l]] - 1] = arr[l];
C[arr[l]] = C[arr[l]] - 1;
}
for (int m = 0; m < 10; ++m) {
cout << B[m] << " ";
}
return 0;
}
Beside that I would like to give you one suggestion that in the loop traverse from right to left as it will maintain the stability of the sort..
Stability means suppose if array has two or more same element then in the stable sort,element which is before in unsorted array will occur first in sorted array.
I want make any matrix[n][n+1] become an upper triangular matrix[n][n+1].
I did this code but that causes a segmentation fault.
void diagonalizarMatriz(float** Matriz, int n){
for(int i = 0; i < n-1; i++)
for(int k = 0; k < n; k ++)
for(int j = n; j >= i; j++)
Matriz[k][j] = Matriz[k][j] - ((Matriz[k][i] * Matriz[i][j]) / Matriz[i][i]);
}
int main(){
float** Matriz = new float* [3];
for(int i = 0; i < 3 ; i++)
Matriz[i] = new float [4];
//test matrix
Matriz[0][0] = 1;
Matriz[0][1] = 4;
Matriz[0][2] = 52;
Matriz[0][3] = 57;
Matriz[1][0] = -27;
Matriz[1][1] = -110;
Matriz[1][2] = -3;
Matriz[1][3] = -134;
Matriz[2][0] = 22;
Matriz[2][1] = 2;
Matriz[2][2] = 14;
Matriz[2][3] = 38;
diagonalizarMatriz(Matriz, 3);
Here
for(int j = n; j >= i; j++)
you start with n at the upper border of the dimensions of your array and the count up,
very soon you therefor access beyond your array, which gets you a segfault if you are lucky.
At a guess you want
for(int j = n; j >= i; j--)
to count down.
UPDATE
Assuming your question is about diagonalizing a matrix (as Eugene claims in the comment section):
In addition to what Yunnosch pointed out, diagonalizing a matrix means that the matrix must be a square n x n. However, in main you're initializing it to be a 3 x 4 matrix.
Original code
float** Matriz = new float* [3];
for(int i = 0; i < 3 ; i++)
Matriz[i] = new float [4];
To get rid of the segfault, change the following part in main (set matrix to 3 x 3):
float** Matriz = new float* [3];
for(int i = 0; i < 3 ; i++)
Matriz[i] = new float [3];
//test matrix
Matriz[0][0] = 1;
Matriz[0][1] = 4;
Matriz[0][2] = 52;
Matriz[1][0] = -27;
Matriz[1][1] = -110;
Matriz[1][2] = -3;
Matriz[2][0] = 22;
Matriz[2][1] = 2;
Matriz[2][2] = 14;
Finally, to get the following matrix (lower-triangular):
1 0 0
4 5 0
7 8 9
Remove the equal sign from your third nested loop:
for(int j = n; j > i; j--)
I assume from here you can work your way through this, to make it an upper-triangular matrix.
OLD ANSWER
Try this:
int matrix[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
int row = 3;
int col = 3;
int i, j;
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
if (i > j) {
cout << "0" << " ";
} else
cout << matrix[i][j] << " ";
}
cout << endl;
}
Will give you this matrix
1 2 3
0 5 6
0 0 9
I don't understand the difference between these two processes (This is all part of a bigger program):
This is the working version:
for (int i = 0; i < 32; i++)
{
int cNumber = decNumb % 2;
binNum[32 - i] = cNumber;
decNumb = decNumb / 2;
}
and this is the version where I get the unintended result:
for(int i = 0; i < 32; i++)
{
int j = 0;
int cNumber = decNum % 2;
binNum[32-j] =cNumber;
decNumb = decNumb / 2;
j++;
}
I don't understand the difference why doing it with an extra variable j gives me a different result. Shouldn't both versions give me the same outcome?
Any help would be appreciated!
edit: added missing opening bracket (typo)
for(int i = 0; i < 32; i++)
int j = 0;
int cNumber = decNum % 2;
binNum[32-j] =cNumber;
decNumb = decNumb / 2;
j++;
}
This does not run because it does not have an open brace for the for loop. In addition, j is reiterated and reset to 0 every loop, so you would not get your desired result. You could have done:
int j = 0;
for(int i = 0; i < 32; i++){
int cNumber = decNum % 2;
binNum[32-j] =cNumber;
decNumb = decNumb / 2;
j++;
}
Otherwise, both codes should run equally fine.
This is Floyd Warshal algorithm which i'm using to find the maximum of minimum path in a graph. Why this algorithm don't work if i put INT_MAX or any other big integer like 2147483647 in place of 100000007.
int main() {
int c,f; //c=number of vertice
// f=number of pair of vertices directly connected
cin >> c >> f;
int graph[c][c];
for(int i = 0;i < c;i++)
for(int j = 0;j < c;j++)
graph[i][j] = 100000007;
for(int i = 0;i < c;i++)
graph[i][i] = 0;
int x,y,p;
for(int i = 0;i < f;i++) {
cin >> x >> y >> p;
graph[x-1][y-1] = p;
graph[y-1][x-1] = p;
}
int dist[c][c], i, j, k;
for(i = 0; i < c; i++)
for (j = 0; j < c; j++)
dist[i][j] = graph[i][j];
for(k = 0; k < c; k++) {
for(i = 0; i < c; i++) {
for(j = 0; j < c; j++) {
if(dist[i][k] + dist[k][j] < dist[i][j])
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
int ans = 0;
for(int i = 0;i < c;i++)
for(int j = 0;j < c;j++)
ans = max(ans,dist[i][j]);
cout << ans << endl;
return 0;
}
(as in the comments)
Once your value for infinity is greater than INT_MAX / 2, which is 1,073,741,823, the line if(dist[i][k] + dist[k][j] < dist[i][j]) has an overflow in it. Overflow is undefined behavior in C++, but the most likely outcome is that dist[i][k] + dist[k][j] becomes a negative value, and in the next line, dist[i][j] = dist[i][k] + dist[k][j];, actual distances get overwritten by such negative values.
The value you need for infinity should be greater than any real distance you can encounter. If that distance exceeds 230 - 1, consider using a type with higher upper limit (unsigned int32, int64, or even a double).
#include <iostream>
int n, m, v1, v2, weight;
cin >> n >> m;
int** graph = new int*[n];
int* distance = new int[n];
int* s = new int[n];
for (int i = 0; i < n; ++i)
graph[i] = new int[n];
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
graph[i][j] = INT_MAX;
for (int i = 0; i < m; ++i)
{
cin >> v1 >> v2 >> weight;
graph[v1][v2] = weight;
graph[v2][v1] = weight;
}
for (int i = 0; i < n; ++i)
distance[i] = INT_MAX;
for (int i = 0; i < n; ++i)
distance[i] = graph[0][i];
for (int i = 0; i < n; ++i)
s[i] = 0;
distance[0] = 0;
int min = INT_MAX;
int vertex = 0;
for (int j = 0; j < n-1; ++j){
min = INT_MAX;
for (int i = 0; i < n; ++i)
if (s[i] == 0 && min >= distance[i])
{
vertex = i;
min = distance[i];
}
s[vertex] = 1;
cout << vertex << " ";
for (int i = 0; i < n; ++i)
if (distance[i]>distance[vertex] + graph[vertex][i])
distance[i] = distance[vertex] + graph[vertex][i];
}
for (int i = 0; i < n; ++i)
cout << distance[i] << " ";
cout << endl;
return 0;
}
Hi. I'm making Dijkstra's algorithm using two-dimentional matrix..
but this code doesn't work. and i don't know why! Can you fix my problem??
i want to make output all distance of graph. but output is looks like array point garbage value like -2345...
Can you help me??
There are some problems in this loop:
for (int i = 0; i < n; ++i)
if (distance[i]>distance[vertex] + graph[vertex][i])
distance[i] = distance[vertex] + graph[vertex][i];
should change to the blew code:
for (int i = 0; i < n; ++i)
if (s[i] == 0 && graph[vertex][i] != INT_MAX && distance[i]>distance[vertex] + graph[vertex][i])
distance[i] = distance[vertex] + graph[vertex][i];
because if the graph[vertex][i] == INT_MAX, the sum of distance[vertex] + graph[vertex][i] is overflow. Another problem is that the vertex i should not be marked before.