wrong output with large test case in union find - c++

I wrote a simple union find implementation using quick find method. Here is my code
#include <iostream>
using namespace std;
class QuickFind
{
int* id;
int size;
public:
QuickFind(int n)
{
id = new int[n];
size = n;
for(int i = 0; i < size; i++) id[i] = i;
}
bool is_connected(int p, int q)
{
return id[p] == id[q];
}
void do_union(int p, int q)
{
int tempP = p;
int tempQ = q;
for(int i = 0; i < size; i++)
{
if(id[i] == tempP) id[i] = tempQ;
}
}
};
int main()
{
QuickFind obj(10000);
obj.do_union(5,6);
obj.do_union(6,8);
cout<<obj.is_connected(5,6)<<endl;
for(int i = 0; i < 1000; i++)cout<<obj.is_connected(i,i+1)<<endl;
return 0;
}
I also wrote a for loop in main. This prints correct answers when I loop it say 50 or 100 times. But it is giving me all 0s when i loop it like 1000 or more times. I'm using codeblocks ide.
Also when i compiled the same code in codechef's online compiler i get correct output. Can anyone tell me about this anomaly?

Related

Coufused about using cpp to achieve selection sort

I tried to implement selection sorting in C++,when i encapsulate the swap function, the output shows a lot of zeros.But at beginning of array codes still work.When I replace swap function with the code in the comment, the output is correct.
I am so confused by this result, who can help me to solve it.
#include <iostream>
#include <string>
using namespace std;
template<class T>
int length(T& arr)
{
return sizeof(arr) / sizeof(arr[0]);
}
void swap(int& a, int& b)
{
a += b;
b = a - b;
a = a - b;
}
int main()
{
int array[] = { 2,2,2,2,6,56,9,4,6,7,3,2,1,55,1 };
int N = length(array);
for (int i = 0; i < N; i++)
{
int min = i; // index of min
for (int j = i + 1;j < N; j++)
{
if (array[j] < array[min]) min = j;
}
swap(array[i],array[min]);
// int temp = array[i];
// array[i] = array[min];
// array[min] = temp;
}
for (int i = 0; i < N; i++)
{
int showNum = array[i];
cout << showNum << " ";
}
return 0;
}
Problem is that your swap function do not work if a and b refer to same variable. When for example swap(array[i], array[i]) is called.
Note in such case, this lines: b = a - b; will set b to zero since a and b are same variable.
This happens when by a chance i array element is already in place.
offtopic:
Learn to split code into functions. Avoid putting lots of code in single function especially main. See example. This is more important the you think.
Your swap function is not doing what it is supposed to do. Just use this instead or fix your current swap.
void swap(int& a, int& b){
int temp = a;
a = b;
b = temp;
}

How to improve my code so that it wouldn't terminate due to timeout?(HackerRank challenge)

My code works pretty well, but when I submit it on HackerRank, it shows me the error of "Your code did not execute within the time limits" for a few cases, and "success" for the rest of the cases.
Here's the link to the HackerRank challenge and what the code is required to do:
https://www.hackerrank.com/challenges/circular-array-rotation/problem
Here's my code:
#include<iostream>
#include<math.h>
using namespace std;
int main()
{
int n, k, q, count=0, index;
cin>>n>>k>>q;
int ar[n];
for (int i = 0; i < n; i++)
{
cin>>ar[i];
}
int m[q];
for (int i = 0; i < q; i++)
{
cin>>m[i];
}
while (count != k)
{
for (int i = n-1; i > 0; i--)
{
swap(ar[i],ar[i-1]);
}
count++;
}
for (int i = 0; i < q; i++)
{
index=m[i];
cout<<ar[index]<<endl;
}
return 0;
}
How about considering setting the starting point of the array to a variable, and calculate this variable to avoid loops.Maybe many loops or int ar[n](I don't know the oj if it supports).
and the solution may like:
for(...){
++pos;
if (pos == k) pos = 0;
}
so what you should do is output the array from pos to end,and 0 to pos
You are doing it in O(N*N) but it can be done in O(N). So I request you to go through this https://www.geeksforgeeks.org/array-rotation/. In case any doubts comment them down.

Extract pair numbers from array

Good evening, folks.
I'm currently experiencing difficulties with extracting pair numbers from an array. I have the following code:
#include <iostream>
using namespace std;
int *paire(int *d, int length) {
int counter = 0;
int position = 0;
for (int i=0; i<length; i++) {
if (d[i] % 2 ==0)
counter++;
}
int *k = new int[counter];
for (int i=0; i<length; i++) {
if (d[i] % 2 ==0) {
k[position] = d[i];
position++;
}
}
return k;
}
int main() {
int b[8] = {1,2,3,4,5,6,7,8};
int *array1 = paire(b,8);
for (int i=0; i<5; i++) { // how can I point here to the counter in paire() ?
cout<<array1[i];
}
delete[] array1;
return 0;
}
So I think I've got it right with initializing the new array in function paire, but I'm having difficulties to iterate through the array.
P.S. I'm first year in university, so I would really be thankful if you can keep the same simplicity in the answers. Thanks in advance!
It appears that you need to return 2 separate values: the number of even numbers in the array b, and the address of the newly allocated memory that is storing exclusively those even numbers.
Since you can not return multiple variables, one solution that does minimal modification to your code would be as follows.
int *paire(int *d, int length, int& counter) {
counter = 0;
// rest of your function remains unchanged
// ...
}
int main() {
int b[8] = {1,2,3,4,5,6,7,8};
int evenNumbers;
int *array1 = paire(b,8, evenNumbers);
for (int i=0; i<evenNumbers; i++) {
cout<<array1[i];
}
delete [] array1;
return 0;
}
Alternatively, you can return the value in counter and send the reference to the int* variable as an argument to paire function. Or, you can declare paire to have return type void and use references to pass back both the values.
You can further simplify your function by allocating to that of the length and returning the counter by an output parameter.
#include <iostream>
using namespace std;
int *paire(int *d, int length, int &counter) {
counter = 0;
int *k = new int[length]; // allocate for the maximum memory
for (int i = 0; i < length; ++i) {
if (d[i] % 2 == 0) {
k[counter++] = d[i];
}
}
return k;
}
int main() {
int b[8] = {1,2,3,4,5,6,7,8};
int counter = 0;
int *array1 = paire(b,8, counter);
for (int i=0; i<counter; i++) { // how can I point here to the counter in paire() ?
cout<<array1[i] << " ";
}
delete [] array1;
return 0;
}
But please note that as others have already pointed out this method is quite error prone in the sense that it leaves the responsibility to the client to delete the internal memory used by paire function.

POSIX pthread_create scrambles the values of variables in a struct, how to avoid that?

So I have my program here:
#include <iostream>
#include <string>
#include <pthread.h>
#include <unistd.h>
#include <math.h>
#include <stdlib.h>
using namespace std;
int const size = 3;
struct Arguments{
int array[];
float result1[];
float result2[];
};
//void calc(int arr[], float rarr1[], float rarr2[], int size);
void* calc(void *param);
int main(int argc, char *argv[]){
time_t t;
srand((unsigned) time(&t));
int arr[size][size] = {};
float rarr1[size][size-1] = {};
float rarr2[size][size-1] = {};
for(int x = 0; x < size; x++){
for(int y = 0; y < size; y++){
int number = rand()%10;
arr[x][y] = number;
}
}
for(int x = 0; x < size; x++){
for(int y = 0; y < size; y++){
cout << arr[x][y] << " ";
}
cout << endl;
}
cout << endl;
/////////////////////////////////////////
pthread_t child;
struct Arguments input;
for(int i = 0; i < size; i++){
input.array[i] = arr[0][i];
}
pthread_create(&child, NULL, calc, (void*)&input);
pthread_join(child, NULL);
//calc(&input);
for(int i = 0; i < size-1; i++){
rarr1[0][i] = input.result1[i];
cout << "Test: " << rarr1[0][i] << endl;
}
//////////////////////////////////
return 0;
}
//void calc(int arr[], float rarr1[], float rarr2[], int size){
void* calc(void *param){
struct Arguments *input = (struct Arguments*)param;
int arr1[] = {};
float rarr1[] = {};
float rarr2[] = {};
for(int i = 0; i < size; i++){
arr1[i] = input->array[i];
}
for(int i = 0; i < size; i++){
int a = arr1[i];
int b = arr1[i+1];
int difference = a-b;
if(difference < 0){
difference = difference * -1;
}
float euc = 1 + pow(difference, 2);
euc = sqrt(euc);
rarr1[i] = euc;
}
for(int i = 0; i <size-1; i++){
input->result1[i] = rarr1[i];
}
for(int i = 0; i <size-1; i++){
int a = arr1[i];
int b = arr1[i+1];
int difference = a-b;
if(difference < 0){
difference = difference * -1;
}
float apar = (difference/rarr1[i]);
float result = asin(apar);
result = result*(180/3.14);
rarr2[i] = result;
}
return NULL;
}
The important part that causes the trouble is between ////// lines but I left the rest of the code for the context, since it might be useful.
So I have the function calc(param); that does the important calculation in the program.
It is working just fine as long as I call it myself (by actually including the function call in the code) and the test loop right after it gives the correct results.
However, when I try to use pthread_create(); to create a new thread that will take care of executing that function, the test loop spits out nonsense and some random huge numbers different each time.
It's kinda weird because the code compiles either way, and literally the only thing that I change is these 2 lines.
What am I doing wrong and why the function spits out garbage when started by the Pthread? Is there a way to fix it?
Ok so if anyone's having a similar problem:
Declare the size of arrays no matter what. It turns out that my program didn't work properly because I initialized my result arrays as float result1[]; instead of float result1[size];

Problems with Floyd-Warshall algorithm implementation

I was trying to sole the second problem from the INOI 2014 paper ie. FREETICKET and used Floyd-Warshall algorithm to compute the answer. My code appears to fail in the final subtask and appears to give WA for a couple test cases.The code follows:
#include <iostream>
#include <cstdio>
#include <climits>
#include <vector>
#include <algorithm>
using namespace std;
typedef vector<long long int> vl;
typedef vector<vl> vvl;
long long int maxelem(const vvl& arr)
{
long long int max = 0, curmax;
for(int i = 0, l = int(arr.size());i < l;i++)
{
curmax = *(max_element(arr[i].begin(), arr[i].end()));
if(curmax > max)
{
max = curmax;
}
}
return max;
}
int main(void)
{
long long int c, f, x, y, p;
scanf("%lld%lld", &c, &f);
vvl adj(c, vl(c, 26336));
for(int i = 0;i < f;i++)
{
scanf("%lld%lld%lld", &x, &y, &p);
adj[x-1][y-1] = p;
adj[y-1][x-1] = p;
}
long long int max = 0;
for(int k = 0;k < c;k++)
{
for(int i = 0;i < c;i++)
{
for(int j = 0;j < i;j++)
{
adj[i][j] = min(adj[i][j], adj[i][k] + adj[k][j]);
}
for(int j = (i + 1);j < c;j++)
{
adj[i][j] = min(adj[i][j], adj[i][k] + adj[k][j]);
}
}
}
max = maxelem(adj);
printf("%lld\n", max);
}
This code just uses an adjacency matrix and ensures that the guy doesn't try to go from the same place, to the same place(in the innermost loop). It fails to solve some of the subtasks from subtask 3 and yields me 50/100 marks. Can anyone help me finding the bug in my code ? I have even tried changing the data type to long long int's.(Just to be safe).
The problem for your algo is:
for(int i = 0;i < f;i++)
{
scanf("%lld%lld%lld", &x, &y, &p);
adj[x-1][y-1] = p;
adj[y-1][x-1] = p;
}
It should be:
for(int i = 0;i < f;i++)
{
scanf("%lld%lld%lld", &x, &y, &p);
adj[x-1][y-1] = min(p, adj[x-1][y-1]);
adj[y-1][x-1] = min(p, adj[y-1][x-1]);
}
Because, if there are multiple routes between city a -> b, we just need to take the cheapest route.
And you also need to set each adj[i][i] = 0 for all 0 <= i < c