Why this IF statement doesn't print inside a loop - c++

Could you please help me out to understand why the If statement is not executing. Thank you for your time.
void allPerfects (int a, int b){
int minVal = minN(a, b);
int maxVal = maxN(a, b);
int sum =0;
vector<int> v;
while (minVal < maxVal){
v.push_back(minVal);
minVal++;
}
for (int i = 0; i < v.size() ;i++){
for (int j = 0; j < i; j++){
sum += v[j];
}
if (sum == v[i]){
printInt(v[i], false); printStr(" is a perfect number!", true);
}
}
}

Even if there aren't any bugs in your code you'll only get a print out for:
allPerfects(a, b);
if there are consecutive integers a, a + 1, ... , a + n that sum up to a + n + 1 < b.
This is only true for:
1 + 2 == 3
and
0 + 1 + 2 == 3
so a has to be 0 or 1 and b has to be greater than or equal to 4.
Edit: But this will only happen if you reset your sum:
for (int i = 0; i < v.size() ;i++){
sum = 0; // This line is missing.
for (int j = 0; j < i; j++){
sum += v[j];
}
if (sum == v[i]){
printInt(v[i], false); printStr(" is a perfect number!", true);
}
}

Related

Leetcode 1588 sum of all ODD length subarrays. C++

I'm practicing myself by doing some leetcode questions, however, I don't know why that's an overflow problem right here. I knew the way I sum the subarray was terrible, any tips for the sum of the subarray?
and the run time for this code would be forever
#include <numeric>
class Solution {
public:
int sumOddLengthSubarrays(vector<int>& arr) {
int size = arr.size();//5
int ans = 0;
int sumAll = 0;
int start = 3;
int tempsum;
for(int i =0; i< size; i++){ //sumitself
sumAll += arr[i];
}
ans = sumAll; //alreayd have the 1 index
if(size%2 == 0){//even number 6
int temp = size-1; //5
if(size == 2)
ans = sumAll;
else{
while(start <= temp){//3 < 5
for(int i = 0; i< size; i++){
for(int k =0; k< start; k++){//3
tempsum += arr[i+k];
if(i+k > temp) //reach 5
break;
}
}
start+=2;
}
}
ans+= tempsum;
}
else{//odd number
if(size == 1)
ans = sumAll;
else{
while(start < size){//3
for(int i = 0; i< size; i++){
for(int k =0; k< start; k++){//3
tempsum += arr[i+k];
if(i+k > size) //reach 5
break;
}
}
start+=2;
}
ans+= tempsum;
ans+= sumAll; //size index
}
}
return ans;
}
};
The problem is with arr[i+k]. The result of i + k can be equal to, or larger, than size. You check it after you have already gone out of bounds.
You should probably modify the inner loop condition so that never happens:
for(int k =0; k < start && (i + k) < size; k++){//3
Now you don't even need the inner check.
You can use prefix sum array technique and then for each index you can calculate the sub-array sum for each odd-length array using prefix sum array. I submitted the below solution in LeetCode and it beats runtime of 100% of submissions and memory usage of 56.95%
class Solution {
public:
int sumOddLengthSubarrays(vector<int>& arr) {
int n = arr.size();
vector<int> prefix(n+1,0);
int sum = 0;
prefix[1] = arr[0];
for(int i=1;i<n;i++)
prefix[i+1]=(arr[i]+prefix[i]);
for(int i=0;i<n;i++)
{
for(int j=i;j<n;j+=2)
sum+=prefix[j+1]-prefix[i];
}
return sum;
}
};
https://leetcode.com/problems/sum-of-all-odd-length-subarrays/discuss/1263893/Java-100-one-pass-O(n)-with-explanation
class Solution {
public int sumOddLengthSubarrays(int[] arr) {
// alt solution: O(n)
//for each i:
// if(n -1 - i) is odd, then arr[i] is counted (n-1-i)/2 + 1 times, each from 0 to i, total ((n-i)/2+1)*(i+1) times
// if(n -1 - i) is even, then arr[i] is counted (n-1-i)/2 + 1 times, if starting subseq index diff with i is even;
// (n-1-i)/2 times, if starting index diff with i s odd, total (n-i)/2 *(i+1) + (i+1)/2
// if i is even i - 1, i - 3, .. 1, total (i -2)/2 + 1 = i / 2 = (i+1) / 2
// if i is odd i-1, i-3, .., 0 total (i-1)/2 + 1 = (i+1) / 2
int total = 0;
int n = arr.length;
for(int i = 0; i < n; i++)
total += (((n - 1 - i) / 2 + 1) * (i + 1) - ((n-i) % 2)*((i+1) / 2)) * arr[i];
return total;
}
}

Why is my largest sub-square-matrix sum program not woring with small matrices with negtive numbers?

This program is meant to take in a square matrix of integers and outputs the largest sub-square-matrix sum.
The first line of input is an integer which indicates the dimension of the square matrix, followed by the actual matrix row-by-row.
My program works almost perfectly except it does not work when using small matrices with negative values. Can anyone help me optimise the code, I cant see where its is going wrong
Example Input1:
3
1 2 3
4 5 6
7 8 9
Output: 45
Example Input2:
3
1 2 3
4 5 6
-7 -8 -9
Output: 16
NB: Since the largest square matrix is [2 3; 5 6] which sums to 16
My code:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int Numberofelements,n,counter = 0,sum=0,result = 0,Maximumvalue = -1, *pointervalue = NULL;
int count = 0;
cin>>n;
int mat[n][n];
int TempMatrix[n][n];
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
cin>>mat[i][j];
if(mat[i][j]<0){
count++;
}
}
}
for (int i = 0; i < n; ++i)
{
for (int j = 0; j< n; ++j)
{
sum = sum + mat[i][j];
}
if (sum > 0 )
{
counter++;
}
sum = 0;
}
Numberofelements = counter;
for (int j = 0; j < n; j++)
{
sum = 0;
for (int i = 0; i < Numberofelements; i++)
{
sum = sum + mat[i][j];
}
TempMatrix[0][j] = sum;
for (int i=1; i<n-Numberofelements+1; i++)
{
sum = sum+(mat[i+Numberofelements-1][j] - mat[i-1][j]);
TempMatrix[i][j] = sum;
}
}
for (int i=0; i<n-Numberofelements+1; i++)
{
sum = 0;
for (int j = 0; j < Numberofelements; j++)
{
sum = sum + TempMatrix[i][j];
}
if (sum > Maximumvalue)
{
Maximumvalue = sum;
pointervalue = &(mat[i][0]);
}
for (int j = 1; j < n-Numberofelements+1; j++)
{
sum = sum + (TempMatrix[i][j+Numberofelements-1] - TempMatrix[i][j-1]);
if (sum > Maximumvalue)
{
Maximumvalue = sum;
pointervalue = &(mat[i][j]);
}
}
}
for (int i = 0; i < Numberofelements; i++)
{
for (int j = 0; j < Numberofelements; j++)
{
result+=*(pointervalue + i*n + j);
}
}
cout << result;
return 0;
}

Dynamic dice sum - modulo

You have d dice, and each die has f faces numbered 1, 2, ..., f.
Return the number of possible ways (out of fd total ways) modulo 10^9 + 7 to roll the dice so the sum of the face up numbers equals target.
My code works well for small values of f,d and target. It gives 0 as answer for big values say 30, 30, 500.
I am getting a lot of difficulty solving where modulo occurs.
What is wrong with my solution ?
int numRollsToTarget(int d, int f, int target)
{
long long int dp[d][target];
for (int i = 0; i < d; i++)
{
for (int j = 0; j < target; j++)
{
dp[i][j] = 0;
}
}
for (int i = 0; i < f && i < target; i++)
{
dp[0][i] = 1;
}
for (int i = 1; i < d; i++)
{
for (int j = 0; j < target; j++)
{
if (j >= i)
for (int k = max(0, j - f); k < min(j, f); k++)
dp[i][j] = (dp[i - 1][j - k - 1] % 1000000007 +
dp[i][j] % 1000000007) % 1000000007;
}
}
return dp[d - 1][target - 1];
}

Find a subarray of m*m (2<=m<n) having largest sum; out of an n*n int array(having +ve, -ve, 0s)

I have written a solution for the above problem but can someone please suggest an optimized way.
I have traversed through the array for count(2 to n) where count is finding subarrays of size count*count.
int n = 5; //Size of array, you may take a dynamic array as well
int a[5][5] = {{1,2,3,4,5},{2,4,7,-2,1},{4,3,9,9,1},{5,2,6,8,0},{5,4,3,2,1}};
int max = 0;
int **tempStore, size;
for(int count = 2; count < n; count++)
{
for(int i = 0; i <= (n-count); i++)
{
for(int j = 0; j <= (n-count); j++)
{
int **temp = new int*[count];
for(int i = 0; i < count; ++i) {
temp[i] = new int[count];
}
for(int k = 0; k < count; k++)
{
for(int l = 0; l <count; l++)
{
temp[k][l] = a[i+k][j+l];
}
}
//printing fetched array
int sum = 0;
for(int k = 0; k < count; k++)
{
for(int l = 0; l <count; l++)
{
sum += temp[k][l];
cout<<temp[k][l]<<" ";
}cout<<endl;
}cout<<"Sum = "<<sum<<endl;
if(sum > max)
{
max = sum;
size = count;
tempStore = new int*[count];
for(int i = 0; i < count; ++i) {
tempStore[i] = new int[count];
}
//Locking the max sum array
for(int k = 0; k < count; k++)
{
for(int l = 0; l <count; l++)
{
tempStore[k][l] = temp[k][l];
}
}
}
//printing finished
cout<<"------------------\n";
//Clear temp memory
for(int i = 0; i < size; ++i) {
delete[] temp[i];
}
delete[] temp;
}
}
}
cout<<"Max sum is = "<<max<<endl;
for(int k = 0; k < size; k++)
{
for(int l = 0; l <size; l++)
{
cout<<tempStore[k][l]<<" ";
}cout<<endl;
}cout<<"-------------------------";
//Clear tempStore memory
for(int i = 0; i < size; ++i) {
delete[] tempStore[i];
}
delete[] tempStore;
Example:
1 2 3 4 5
2 4 7 -2 1
4 3 9 9 1
5 2 6 8 0
5 4 3 2 1
Output:
Max sum is = 71
2 4 7 -2
4 3 9 9
5 2 6 8
5 4 3 2
This is a problem best solved using Dynamic Programming (DP) or memoization.
Assuming n is significantly large, you will find that recalculating the sum of every possible combination of matrix will take too long, therefore if you could reuse previous calculations that would make everything much faster.
The idea is to start with the smaller matrices and calculate sum of the larger one reusing the precalculated value of the smaller ones.
long long *sub_solutions = new long long[n*n*m];
#define at(r,c,i) sub_solutions[((i)*n + (r))*n + (c)]
// Winner:
unsigned int w_row = 0, w_col = 0, w_size = 0;
// Fill first layer:
for ( int row = 0; row < n; row++) {
for (int col = 0; col < n; col++) {
at(r, c, 0) = data[r][c];
if (data[r][c] > data[w_row][w_col]) {
w_row = r;
w_col = c;
}
}
}
// Fill remaining layers.
for ( int size = 1; size < m; size++) {
for ( int row = 0; row < n-size; row++) {
for (int col = 0; col < n-size; col++) {
long long sum = data[row+size][col+size];
for (int i = 0; i < size; i++) {
sum += data[row+size][col+i];
sum += data[row+i][col+size];
}
sum += at(row, col, size-1); // Reuse previous solution.
at(row, col, size) = sum;
if (sum > at(w_row, w_col, w_size)) { // Could optimize this part if you only need the sum.
w_row = row;
w_col = col;
w_size = size;
}
}
}
}
// The largest sum is of the sub_matrix starting a w_row, w_col, and has dimensions w_size+1.
long long largest = at(w_row, w_col, w_size);
delete [] sub_solutions;
This algorithm has complexity: O(n*n*m*m) or more precisely: 0.5*n*(n-1)*m*(m-1). (Now I haven't tested this so please let me know if there are any bugs.)
Try this one (using naive approach, will be easier to get the idea):
#include <iostream>
#include<vector>
using namespace std;
int main( )
{
int n = 5; //Size of array, you may take a dynamic array as well
int a[5][5] =
{{2,1,8,9,0},{2,4,7,-2,1},{5,4,3,2,1},{3,4,9,9,2},{5,2,6,8,0}};
int sum, partsum;
int i, j, k, m;
sum = -999999; // presume minimum part sum
for (i = 0; i < n; i++) {
partsum = 0;
m = sizeof(a[i])/sizeof(int);
for (j = 0; j < m; j++) {
partsum += a[i][j];
}
if (partsum > sum) {
k = i;
sum = partsum;
}
}
// print subarray having largest sum
m = sizeof(a[k])/sizeof(int); // m needs to be recomputed
for (j = 0; j < m - 1; j++) {
cout << a[k][j] << ", ";
}
cout << a[k][m - 1] <<"\nmax part sum = " << sum << endl;
return 0;
}
With a cumulative sum, you may compute partial sum in constant time
std::vector<std::vector<int>>
compute_cumulative(const std::vector<std::vector<int>>& m)
{
std::vector<std::vector<int>> res(m.size() + 1, std::vector<int>(m.size() + 1));
for (std::size_t i = 0; i != m.size(); ++i) {
for (std::size_t j = 0; j != m.size(); ++j) {
res[i + 1][j + 1] = m[i][j] - res[i][j]
+ res[i + 1][j] + res[i][j + 1];
}
}
return res;
}
int compute_partial_sum(const std::vector<std::vector<int>>& cumulative, std::size_t i, std::size_t j, std::size_t size)
{
return cumulative[i][j] + cumulative[i + size][j + size]
- cumulative[i][j + size] - cumulative[i + size][j];
}
live example

SubsetSum Printing the list

The problem is to print all subsets that sum up to a value. I wrote code to check if there is a possible subset. Can some one gimme an idea to print the numbers that form the sum. Below is my code. Assume the array contains only +ve nos for simplicity.
void subsetsum(int A[], int target) {
int N = sizeof(A)/sizeof(int), sum = 0;
for(int i = 0; i < N; i++) sum += A[i];
vector<bool> V(sum + 1, 0);
V[0] = 1;
for(int i = 0; i < N; i++)
for(int j = sum; j >= 0; j--) {
if(j + A[i] <= sum && V[j]) V[A[i] + j] = 1;
}
if(V[target]) cout << "Sumbset sum exists" << endl;
else cout << "Sumbset sum doesnt exist" << endl;
}
First you need to generate all the subsets
If [a,b,c,d] is given array, think about generating subsets taking each element from array one at a time.
subsets(X) including y = foreach x in X append y to x
Taking a, we get subsets(a) = { [], [a] }
Take b, we get subsets(a,b) = subsets(a) + (subsets(a) including b)
= { [], [a] } + { [b], [a,b] } = { [], [a], [b], [a,b] }
Take c, subsets(a,b,c) = subsets(a,b) + (subsets(a,b) including c)
= {[], [a],[b],[a,b]} + {[c], [a,c], [b,c], [a,b,c]}
Once you get all subsets, print those whose sums equals target. You can modify the above algo further if you don't need any subsets.
Here's an answer in javascript:
function subsetsum(A, target) {
//int N = sizeof(A)/sizeof(int), sum = 0;
var N = A.length, sum = 0;
//for(int i = 0; i < N; i++) sum += A[i];
for(var i = 0; i < N; i++) sum += A[i];
// vector<bool> V(sum + 1, 0);
var V = [];
V[0] = [];
for(var i = 0; i < N; i++) {
for(var j = sum; j >= 0; j--) {
if(j + A[i] <= sum && V[j]) {
//Join the subset of the memoized result to this result.
V[A[i] + j] = [A[i]].concat(V[j]);
}
}
}
console.log(V);
//evaluates to true if V[target] exists
return !!V[target];
}
function to find power set of a vector<int>
vector<vector<int>> power_set(const vector<int>& nums) {
if (nums.empty()) { return { {} }; }
auto set = power_set(vector<int>(begin(nums) +1, end(nums)));
auto tmp = set;
for (auto& p : tmp) {
p.push_back(nums[0]);
}
set.insert(end(set), begin(tmp), end(tmp));
return set;
}
function that return all sets in the power set that sum to target
vector<vector<int>> test_sum(const vector<vector<int>>& ps, int target) {
vector<vector<int>> v;
for (auto& p : ps) {
int sum = accumulate(begin(p), end(p), 0);
if (sum == target) {
v.push_back(p);
}
}
return v;
}
I modified your code to print the numbers.
void subsetsum(int A[], int target) {
int N = sizeof(A) / sizeof(int), sum = 0;
for (int i = 0; i < N; i++) sum += A[i];
vector<bool> V(sum + 1, 0);
V[0] = 1;
for (int i = 0; i < N; i++)
for (int j = sum; j >= 0; j--) {
if (j + A[i] <= sum && V[j]) V[A[i] + j] = 1;
}
if (V[target]) cout << "Sumbset sum exists" << endl;
else cout << "Sumbset sum doesnt exist" << endl;
if (V[target])
{
for (int i = N - 1; i >= 0; i--)
{
if (V[target - A[i]] == 1) printf("%d, ", A[i]), target -= A[i];
}
printf("\n");
}
}
or Here's my version with vector
bool subsetsum_dp(vector<int>& v, int sum)
{
int n = v.size();
const int MAX_ELEMENT = 100;
const int MAX_ELEMENT_VALUE = 1000;
static int dp[MAX_ELEMENT*MAX_ELEMENT_VALUE + 1]; memset(dp, 0, sizeof(dp));
dp[0] = 1;
for (int i = 0; i < n; i++)
{
for (int j = MAX_ELEMENT*MAX_ELEMENT_VALUE; j >= 0; j--)
{
if (j - v[i] < 0) continue;
if (dp[j - v[i]]) dp[j] = 1;
}
}
if (dp[sum])
{
for (int i = n - 1; i >= 0; i--)
{
if (dp[sum - v[i]] == 1) printf("%d, ", v[i]), sum -= v[i];
}
printf("\n");
}
return dp[sum] ? true : false;
}