Following coding problem SIGSEGV Runtime Error - c++

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main() {
int T;
cin>>T;
do{
vector<int> ans;
int N=0;
cin>>N;
vector<int> attackArray(N), defArray(N);
for (int i =0; i<N; i++) {
cin>>attackArray[i];
}
for (int i =0; i<N; i++) {
cin>>defArray[i];
}
for (int i =0; i<N; i++) {
int nexti, previ;
if (i == 0)
{
nexti = 1;
previ = N - 1;
}
else if (i == N - 1)
{
nexti = 0;
previ = N - 2;
}
else
{
nexti = i + 1;
previ = i - 1;
}
if (defArray[i] > attackArray[nexti] &&
defArray[i] > attackArray[previ] &&
defArray[i] > attackArray[nexti] + attackArray[previ]){
ans.push_back(defArray[i]);
}
else {ans.push_back(-1); break;}
}
sort(ans.begin(), ans.end(), greater<int>());
cout<<ans[0]<<endl;
T--;
}while (T !=0);
return 0;
}
Input
The first line of the input contains a single integer T denoting the number of test cases. The description of T test cases follows.
The first line of each test case contains a single integer N.
The second line contains N space-separated integers a1,a2,…,aN.
The third line contains N space-separated integers d1,d2,…,dN.
Output
For each test case, print a single line containing one integer ― the best defense value of the shield the king gets, or −1 if Chef can be thrown in the snake pit.
Example
2
4
1 1 4 1
3 4 2 1
7
5 4 5 4 5 4 5
3 2 4 7 2 5 9
Example Output
3
-1

The problem is that your sequence of if statements should be one if ... else if ... else statement.
if (i == 0)
...
else if (i==N-1)
...
else
...
Just because a previous if condiition has evaluated to true doesn't stop code after the if statement from executing unless you use an else. So the condition in your third if statement is executing even when i == 0 or i == N - 1, resulting in an out of bounds array access and a crash.
Also
int attackArray[N],defArray[N];
is not legal C++ because all array sizes must be compile time constants. You are clearly using a compiler which doesn't care, but you should, so use this instead
vector<int> attackArray(N), defArray(N);
Finally there's a lot of duplicated code in your different conditions. You could simplify a lot by adding a couple of extra variables for the next and previous values of i. E.g.
int nexti, previ;
if (i == 0)
{
nexti = 1;
previ = N - 1;
}
else if (i == N - 1)
{
nexti = 0;
previ = N - 2;
}
else
{
nexti = i + 1;
previ = i - 1;
}
if (defArray[i] > attackArray[nexti] &&
defArray[i] > attackArray[previ] &&
defArray[i] > attackArray[nexti] + attackArray[previ])
...

Related

How can I return the turbulence sequence with a complexity of O(n)?

#include <iostream>
#include <utility>
using namespace std;
pair<int,int> findLongestTurbulence(int arr[], int n){
pair<int,int> ret = {0,-1};
int a = -1;
for(int start = 0; start < n ; start++ ){
a = -1;
for(int end = start+1; end < n ; end ++){
if(a == -1){
if(arr[end] > arr[end-1])
a=1;
else if( arr[end] < arr[end-1])
a=0;
else {
// no sequence can be generated starting with start
if(end - start > ret.second - ret.first)
ret = {start,start};
break; // CHECK FOR NEXT STARTING POINT
}
}
else if(a == 0){
if(arr[end] > arr[end-1]){
a = 1;
}
else{
// return this start and end point as this sequence cannot be extended more
if(end - start > ret.second - ret.first)
ret = { start, end-1};
break;
}
}
else{
if(arr[end] < arr[end-1]){
a = 0;
}
else{
// return this start and end point as this sequence cannot be extended more
if(end - start > ret.second - ret.first)
ret = { start, end-1};
break;
}
}
}
}
return ret;
}
int main()
{
int arr[] = {1,8,5,2,6,3,9,7,4,2,3}; // provided sequence
int n = sizeof(arr)/sizeof(arr[0]);
pair<int,int> ans = findLongestTurbulence(arr,n);
for(int i=ans.first;i<ans.second;i++){
cout<<arr[i]<<", ";
}
cout<<arr[ans.second]<<endl;
}
My assumption was that it is O(n^2) as it has two nested for loops. The goal this code is trying to achieve is to find a longest turbulence in the
sequence.
‘Turbulence’ is a consecutive sub-sequence where the numbers rise and drop alternately. Every subsequence of a turbulence is also a turbulence.
For example,
• 1 and 8 and 5 are all turbulences because each of them contains only one number.
• 1,8 and 8,5 are both turbulences because 1 rises to 8 in the first sequence and 8 drops to 5 in the second.
• 1,8,5 is a turbulence because 1 rises to 8 and then drops to 5.
• 8,5,2 is not a turbulence because 8 drops twice (first to 5 and then to 2).
• The longest turbulence in the given sequence is 5,2,6,3,9,7 which is also the output.
I think the time complexity of this function is O (n^2) as there are two nested for loops. How would I return the turbulence sequence with a complexity of O(n)?
I admit that your code is too complicated for me. I tried it, but I dont understand it. Anyhow, it can be done with a single loop. To keep it simple I would use two loops (though not nested!). One loop to see if arr[i] < arr[i+1] or arr[i] > arr[i+1].
Also too keep it simple you can exclude the case of arr[i] == arr[i+1] because when the array has subsequent elements that are equal then you can apply the algorithm on sub arrays. A turbulence never contains elements arr[i] == arr[i+1].
To invent some fance name I call it "polarity" +1 when arr[i] > arr[i+1] and -1 when arr[i] < arr[i+1] at even i. At odd indices polarity is reversed (ie -1 when arr[i] > arr[i+1]).
This is what you'll get:
#include <vector>
#include <iostream>
#include <iomanip>
int main()
{
int arr[] = {1,8,5,2,6,3,9,7,4,2,3};
std::vector<int> polarity;
int flip = 1;
for (size_t i = 0; i < std::size(arr) -1; ++i){
if (arr[i] > arr[i+1]) polarity.push_back(1*flip);
else polarity.push_back(-1*flip);
flip *= -1;
}
for (size_t i = 0; i< std::size(arr); ++i) {
std::cout << std::setw(5) << arr[i] << " ";
}
std::cout << "\n";
for (size_t i = 0; i < std::size(arr)-1; ++i) {
std::cout << std::setw(5) << polarity[i] << " ";
}
}
Output:
1 8 5 2 6 3 9 7 4 2 3
-1 -1 1 1 1 1 1 -1 1 1
I'll leave it to you to find the longest subsequence of equal elements in polarity. In this example it is polarity 1 starting at the element with value 5 till 7 (the last entry with polarity 1 corresponds to elements 9 and 7, thats why 7 is included).

C++: Dynamic programming, given 3 possible operations

Question:
So the question goes like this: I have N numbers. For each number X in the array of length N, I can perform 3 operations: 1. If X is a multiple of 2, divide X by 2. 2. If X is a multiple of 3, divide it by 3. 3. Subtract 1 from X. Find the minimum number of operations to make X = 0. This code is meant to be done using dynamic programming...
Input:
line 1: N line 2: Array X of N numbers
Output:
line 1: Number of operations to reduce X1 to 0. ... line N: Number of operations to reduce XN to 0.
So how should I go about doing this?
Code:
#include <bits/stdc++.h>
using namespace std;
int main(){
int N;
cin >> N;
for (int i = 0; i < N; i++){
int A, count = 0;
cin >> A;
while (A > 0){
if (A%2 == 0){
A /= 2;
count++;
}
else if (A%3 == 0){
A /= 3;
count++;
}
else{
A--;
count++;
}
}
cout << count << "\n";
}
}
This code which I currently have in mind does not work for some cases(meaning I do not output the desired solution, and that the code is a working code), say Xi = 10. My code does 10/2, then -1, then /2, then /2 then -1, so it is 5 operations. However, the optimal is 10 -1, /3, /3 again, then -1, which is 4 operations. Anyone has any idea how I should code my solution to this problem? Thanks! Any help is appreciated!
You said dynamic programming:
std::vector<int> v{0};
for (int i = 1; i != N + 1; ++i) {
v.push_back(v.back() + 1);
if (i % 2 == 0) {
v.back() = std::min(v.back(), v[i / 2] + 1);
}
if (i % 3 == 0) {
v.back() = std::min(v.back(), v[i / 3] + 1);
}
}
return v.back();

Improving optimization of nested loop

I'm making a simple program to calculate the number of pairs in an array that are divisible by 3 array length and values are user determined.
Now my code is perfectly fine. However, I just want to check if there is a faster way to calculate it which results in less compiling time?
As the length of the array is 10^4 or less compiler takes less than 100ms. However, as it gets more to 10^5 it spikes up to 1000ms so why is this? and how to improve speed?
#include <iostream>
using namespace std;
int main()
{
int N, i, b;
b = 0;
cin >> N;
unsigned int j = 0;
std::vector<unsigned int> a(N);
for (j = 0; j < N; j++) {
cin >> a[j];
if (j == 0) {
}
else {
for (i = j - 1; i >= 0; i = i - 1) {
if ((a[j] + a[i]) % 3 == 0) {
b++;
}
}
}
}
cout << b;
return 0;
}
Your algorithm has O(N^2) complexity. There is a faster way.
(a[i] + a[j]) % 3 == ((a[i] % 3) + (a[j] % 3)) % 3
Thus, you need not know the exact numbers, you need to know their remainders of division by three only. Zero remainder of the sum can be received with two numbers with zero remainders (0 + 0) and with two numbers with remainders 1 and 2 (1 + 2).
The result will be equal to r[1]*r[2] + r[0]*(r[0]-1)/2 where r[i] is the quantity of numbers with remainder equal to i.
int r[3] = {};
for (int i : a) {
r[i % 3]++;
}
std::cout << r[1]*r[2] + (r[0]*(r[0]-1)) / 2;
The complexity of this algorithm is O(N).
I've encountered this problem before, and while I don't find my particular solution, you could improve running times by hashing.
The code would look something like this:
// A C++ program to check if arr[0..n-1] can be divided
// in pairs such that every pair is divisible by k.
#include <bits/stdc++.h>
using namespace std;
// Returns true if arr[0..n-1] can be divided into pairs
// with sum divisible by k.
bool canPairs(int arr[], int n, int k)
{
// An odd length array cannot be divided into pairs
if (n & 1)
return false;
// Create a frequency array to count occurrences
// of all remainders when divided by k.
map<int, int> freq;
// Count occurrences of all remainders
for (int i = 0; i < n; i++)
freq[arr[i] % k]++;
// Traverse input array and use freq[] to decide
// if given array can be divided in pairs
for (int i = 0; i < n; i++)
{
// Remainder of current element
int rem = arr[i] % k;
// If remainder with current element divides
// k into two halves.
if (2*rem == k)
{
// Then there must be even occurrences of
// such remainder
if (freq[rem] % 2 != 0)
return false;
}
// If remainder is 0, then there must be two
// elements with 0 remainder
else if (rem == 0)
{
if (freq[rem] & 1)
return false;
}
// Else number of occurrences of remainder
// must be equal to number of occurrences of
// k - remainder
else if (freq[rem] != freq[k - rem])
return false;
}
return true;
}
/* Driver program to test above function */
int main()
{
int arr[] = {92, 75, 65, 48, 45, 35};
int k = 10;
int n = sizeof(arr)/sizeof(arr[0]);
canPairs(arr, n, k)? cout << "True": cout << "False";
return 0;
}
That works for a k (in your case 3)
But then again, this is not my code, but the code you can find in the following link. with a proper explanation. I didn't just paste the link since it's bad practice I think.

C programming , array not printing properly

So for class we are doing some encryption/ decryption algorithms with prime numbers. I am in the first part of making the program. I am trying to get the program to check if a number is prime or not. After this, I want the program to store all prime numbers before that number in an array called prime_array. And I was trying to get those results to print out on the screen. It's not working the way I intended. I'm later going to use this in decryption of something a bit more complex. Just wandering if anyone could see what part of my code is causing the issues.
Code:
#include <stdio.h>
int main()
{
int n;
int prime;
int prime_array[1000];
int prime_answer;
int j=0;
printf("enter a number for n : ");
scanf_s("%d", &n);
if (n % 2 == 1)
{
printf("Number is prime.");
getchar();
getchar();
for (int i = 0; i <= n; i++)
{
if (n - 1 % 2 == 1)
{
n--;
prime_array[j] = n;
j++;
}
else
{
// do nothing
}
}
}
else if (n % 2 == 0)
{
printf("Number is not prime.");
getchar();
getchar();
}
for (int k = 0; k<= 10; k++)
{
printf("\n\n %d",prime_array[k]);
if (k == 10);
{
getchar();
getchar();
}
}
}
Problem is this condition-
if (n - 1 % 2 == 1)
This exression is treated as (n-(1 % 2))==1 , because % has higher precedence than - ,therefore , 1 % 2 is evaluated first .As 1 % 2 is 1 and expression become n-1 ,so condition will not be true until n is 2 (not as you would desire ) .
You need to write like this -
if ((n - 1) % 2 == 1)

Brute Force Permutation Swapping

I've been working on a brute force algorithm to generate all permutations of a given set. Eventually, I want to feed each of these permutations into a nxn matrix to test if it is a valid magic square or not.
--I KNOW THAT THERE IS A WAY TO GENERATE A MAGIC SQUARE EASILY--
That is not what I want to do, though. I'm focusing on the brute force aspect of it.
For a set of 3 elements, it works wonderfully. However, once I use 4 or more elements, I lose out on a few permutations. Just from looking at the output of 4, I am missing 7 permutations.
#include <stdio.h>
#include <iostream>
using namespace std;
//ms = magic square
//n = size
void perm(int ms[], int n) {
int pivot = 0;
int index = 0;
int pivBit = 1;
int fin = 0;
int hold = 0;
//While we are not finished
while (fin == 0) {
//Incriment the index
++index;
if (index >= n) {
index = 0;
}
//if index is equal to the pivot
if (index == pivot) {
//Is this the first time visiting the pivot?
if (pivBit == 0) {
//Are we at the beginning again?
if (index == 0 && pivot == 0)
{
fin = 1;
}
pivBit = 1;
++index;
}
//Second time visiting?
else {
pivBit = 0;
++pivot;
if (pivot >= n) {
pivot = 0;
}
}
}
//If we are out of bounds
if (index >= n) {
index = 0;
}
//swap
hold = ms[index];
ms[index] = ms[pivot];
ms[pivot] = hold;
for (int i = 0; i < n; ++i) {
cout << ms[i];
if (i < n - 1) {
cout << ", ";
}
else {
cout << endl;
}
}
}
}
int main() {
cout << "Are you ready to brute force, my brother?" << endl;
//Set
int magicsquare[] = { 1, 2, 3, 4};
int size = 4;
perm(magicsquare, size);
getchar();
return 0;
}
My output is:
2 1 3 4
3 1 2 4
4 1 2 3
1 4 2 3
1 2 4 3
1 3 4 2
3 1 4 2
3 4 1 2
3 4 2 1
2 4 3 1
2 3 4 1
2 3 1 4
4 3 1 2
4 2 1 3
4 2 3 1
1 2 3 4
2 1 3 4
Looking at it, I can already see that I am missing both 1 4 3 2 and 1 3 2 4.
Where've I gone wrong in my algorithm?
The wiki article on permutation includes a common algorithm used to produce all permutations in lexicographic order, starting with an array of sequentially increasing integers, ending with that array reversed. wiki next permutation.
If dealing with an array of objects, you can generate an array of indices 0 through n-1 and use next permutation on the indices to produce all permutations of the array of objects.
You can also do a web search for next permutation to find similar algorithms. The recursive ones produce all permutations, but not in lexicographic order.
The simplest way to generate all permutations is recursive. For each i, swap the i'th element to the 0 position. Then recursively find all permutations of of the remaining array.
int buf[1000], n; // better to wrap these in a class...
void permute(int *a, int a_len) {
if (a_len == 1) {
for (int i = 0; i < n; i++) printf("%d ", buf[i]);
printf("\n");
} else {
for (int i = 0; i < a_len; i++) {
swap(a, 0, i);
permute(a + 1, a_len - 1);
swap(a, 0, i);
}
}
}
void run(int buf_len) {
for (int i = 0; i < buf_len; i++) buf[i] = i + 1;
n = buf_len;
permute(buf, buf_len);
}
This assumes no repeated elements in the original array. It's not to hard to have it take repeated elements into account.