Minimum difference in an array - c++

I want to find the minimum difference among all elements of an array. I read through various other questions, but couldn't find the exact source of the error in the following code.
#include<iostream>
#include<stdio.h>
#include<cstdlib>
using namespace std;
void quicksort(long int *lp, long int *rp);
int main()
{
int t,n;
long int s[5000];
cin>>t;
while(t--){
cin>>n;
for(int i=0;i<n;i++) cin>>s[i];
quicksort(&s[0],&s[n-1]);
//cout<<"passes:"<<passes<<endl;
//for(int i=0;i<n;i++) cout<<s[i]<<" ";
long int min = abs(s[1]-s[0]);
//cout<<endl<<min;
for(int i=1;i<(n-1);i++){
long int temp = abs(s[i]-s[i+1]);
if (temp <= min) min = temp;
}
cout<<min;
}
}
void quicksort(long int *lp,long int *rp){
int arraysize= (rp-lp)+1;
if(arraysize > 1){
long int *pivot = (lp+(arraysize/2));
long int swap=0;
long int *orgl = lp;
long int *orgr = rp;
while(lp!=rp){
while (*lp < *pivot) lp++;
while (*rp > *pivot) rp--;
if (lp == pivot) pivot=rp;
else if (rp == pivot) pivot=lp;
swap = *lp;
*lp = *rp;
*rp = swap;
if((*lp == *pivot) || ( *rp == *pivot)) break;
}
quicksort(orgl,pivot-1);
quicksort(pivot+1,orgr);
}
}
The problem statement is given in this link : http://www.codechef.com/problems/HORSES
Can you please identify the error in my program ?

You are using C++ so instead of using your custom quicksort which is not really guarantee O(n*logn) you better use sort from <algorithm>.
This logic looks good:
long int min = abs(s[1]-s[0]);
//cout<<endl<<min;
for(int i=1;i<(n-1);i++){
long int temp = abs(s[i]-s[i+1]);
if (temp <= min) min = temp;
}
By the way:
cout<<min;
Add cout<<min << endl;

The line
if((*lp == *pivot) || ( *rp == *pivot)) break;
is wrong. Consider
5 4 7 5 2 5
^
pivot
Oops.
This line
long int temp = abs(s[i]-s[i+1]);
is unnecessarily complex. Since the array is (supposedly) sorted,
long int temp = s[i+1] - s[i];
does the same without calling abs.

sort(s, s + n); // #include <algorithm> O(n*log n)
Otherwise sort/find minimum algorithm is correct. There are O(n) algorithms based on randomization, bucket sort.
#include <algorithm> // sort()
#include <iostream>
int main() {
using namespace std;
int ntests, n;
const int maxn = 5000; // http://www.codechef.com/problems/HORSES
int s[maxn];
cin >> ntests; // read number of tests
while (ntests--) {
cin >> n; // read number of integers
for (int i = 0; i < n; ++i) cin >> s[i]; // read input array
sort(s, s + n); // sort O(n*log n)
// find minimal difference O(n)
int mindiff = s[1] - s[0]; // minn = 2
for (int i = 2; i < n; ++i) {
int diff = s[i] - s[i-1];
if (diff < mindiff) mindiff = diff;
}
cout << mindiff << endl;
}
}

#include <iostream> using namespace std;
int main() {
int a[] = {1,5,2,3,6,9};
int c=0;
int n = sizeof(a)/sizeof(a[0]);
for(int i=0;i<n-1;i++){
for(int j=i+1;j<n;j++){
cout<<a[i]<<" - "<<a[j]<<" = "<<a[i]-a[j]<<endl;
if(abs(a[i]-a[j]) == 2)
c++;
}
}
cout<<c<<endl;
return 0; }

Related

We have to maximize the modulo function

In this question we have to maximize the modulo function. A string is given And we have remove the element and check after removing a element which number give the maximum modulo answer.
Link:- https://www.hackerearth.com/practice/data-structures/arrays/1-d/practice-problems/algorithm/maximize-modulo-2-0cb15ded/
My code is not able to pass all test case it shows runtime error or wrong answer in most test case.
#include "bits/stdc++.h"
using namespace std;
int countDigit(long long n)
{
int count = 0;
while (n != 0)
{
n = n / 10;
++count;
}
return count;
}
int main() {
int t;
cin>>t;
for(int i=0;i<t;i++){
int m,k;
cin>>m>>k;
string s;
cin>>s;
int ans = INT_MIN;
int n = countDigit(k);
if(n == m && stoi(s) < k){
cout<<stoi(s)<<endl;
continue;
}
else{
for(int i=0;i<m;i++){
string a = "";
for(int j=0;j<m;j++){
if(j == i){
continue;
}
else{
a += s[j];
}
}
int mo;
int num = stoi(a);
mo = num%k;
if(mo > ans){
ans = mo;
}
}
cout<<ans<<endl;
}
}
return 0;
}
Please tell me where i'm making the mistake or please tell me any better way to solve this question?

Top Down Approach for this dynamic programming problem

Here is the problem-
You are given array B of size n. You have to construct array A such that 1<=A[i]<=B[i] and sum of the absolute difference of consecutive pairs of A is maximized ,that is, summation of abs(A[i]-A[i-1]) is maximised.You have to return this cost.
Example B=[1,2,3] A can be [1,2,1],[1,1,3],[1,2,3] In all these cases cost is 2 which is the maximum.
Constraints n<=10^5 ,1<=B[i]<=100
Here is my approach -
Cost will be maximum when A[i]=1 or A[i]=B[i]
So I created dp[idx][flag][curr] of size [100002][2][102] where it calculates the cost till index idx. flag will be 0 or 1 representing if A[i] should be 1 or B[i] respectively. curr will be the value of A[i] depending upon flag
Here is my code
#include<bits/stdc++.h>
using namespace std;
#define boost ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
typedef long long int ll;
#define mod 1000000007
ll n;
ll dp[100002][2][101];
ll b[100005];
ll solve(ll idx,ll flag,ll curr)
{
if(idx>=n)
return 0;
ll s1=0;
if(dp[idx][flag][curr]!=-1)
return dp[idx][flag][curr];
if(idx==0)
{
int left=solve(idx+1,0,curr);
int right=solve(idx+1,1,curr);
return dp[idx][flag][curr]=max(left,right);
}
else
{
if(flag==0)
{
s1=abs(curr-1);
return dp[idx][flag][curr]=s1+max(solve(idx+1,0,1),solve(idx+1,1,1));
}
else
{
s1=abs(b[idx]-curr);
return dp[idx][flag][curr]=s1+max(solve(idx+1,0,b[idx]),solve(idx+1,1,b[idx]));
}
}
}
int main()
{
boost
ll t;
cin>>t;
while(t--)
{
cin>>n;
memset(dp,-1,sizeof(dp));
ll res=0;
for(int i=0;i<n;i++)
cin>>b[i];
ll s1=solve(0,0,1);//Starting from idx 0 flag 0 and value as 1
ll s2=solve(0,1,b[0]);//Starting from idx 0 flag 1 and value as B[0]
cout<<max(s1,s2)<<"\n";
}
}'
Is there any way to reduce states of dp or any other top down solution because my code fails if values of B[i] are large
You implement a recursive approach. Here, a simple iterative implementation allows to get a time efficiency of O(n) and a space efficiency of O(1)
(not counting the space needed for the input array).
You correctly stated that at index i, we have two choices only, a[i]=1 (flag = 0) or a[i]=b[i] (flag = 1)
The basic idea is that, when studying what choice to make at index i, we only need to know what are the optimum sums ending at index i-1, for flag = 0 (sum0) or flag = 1 (sum1).
We don't need to explicitely calculate the array a[.].
Note: I kept long long int as in your code, but it seems that int is quite enough here.
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <algorithm>
#define mod 1000000007 // needed ???
long long int sum_diff (const std::vector<long long> &b) {
int n = b.size();
long long int sum0 = 0;
long long int sum1 = 0;
for (int i = 1; i < n; ++i) {
long long int temp = std::max (sum0, sum1 + b[i-1] - 1); // flag = 0: a[i] = 1
sum1 = std::max (sum0 + b[i] - 1, sum1 + std::abs(b[i] - b[i-1])); // flag = 1: a[i] = b[i]
sum0 = temp;
}
return std::max (sum0, sum1);
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int t;
std::cin >> t;
while(t--) {
int n;
std::cin >> n;
std::vector<long long int> b(n);
for(int i = 0;i < n; i++) std::cin >> b[i];
long long int s = sum_diff (b);
std::cout << s << "\n";
}
}
As you insist to have a top-down (recursive) aproach, I have implement both approaches in the following code. But I insist that the iterative solution is better in this case.
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
int sum_diff (const std::vector<int> &b) {
int n = b.size();
int sum0 = 0;
int sum1 = 0;
for (int i = 1; i < n; ++i) {
int temp = std::max (sum0, sum1 + b[i-1] - 1); // flag = 0: a[i] = 1
sum1 = std::max (sum0 + b[i] - 1, sum1 + std::abs(b[i] - b[i-1])); // flag = 1: a[i] = b[i]
sum0 = temp;
}
return std::max (sum0, sum1);
}
void sum_diff_recurs (const std::vector<int> &b, int i, int&sum0, int &sum1) {
if (i == 0) {
sum0 = sum1 = 0;
return;
}
sum_diff_recurs (b, i-1, sum0, sum1);
int temp = std::max (sum0, sum1 + b[i-1] - 1); // flag = 0: a[i] = 1
sum1 = std::max (sum0 + b[i] - 1, sum1 + std::abs(b[i] - b[i-1])); // flag = 1: a[i] = b[i]
sum0 = temp;
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int t;
std::cin >> t;
while(t--) {
int n, sum0, sum1;
std::cin >> n;
std::vector<int> b(n);
for(int i = 0; i < n; i++) std::cin >> b[i];
int s = sum_diff (b);
std::cout << s << "\n";
sum_diff_recurs (b, n-1, sum0, sum1);
std::cout << std::max(sum0, sum1) << "\n";
}
}
Actually I found the solution using only two states idx and flag
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
ll n,k;
ll dp[100002][2];
ll b[100005];
ll solve(ll idx,ll flag)
{
if(idx>=n-1)
return 0;
if(dp[idx][flag]!=-1)
return dp[idx][flag];
ll val=(flag==1)?b[idx]:1;
ll left=solve(idx+1,0)+val-1;
ll right=solve(idx+1,1)+abs(val-b[idx+1]);
return (dp[idx][flag]=max(left,right));
}
int main()
{
ll t;
cin>>t;
while(t--)
{
cin>>n;
memset(dp,-1,sizeof(dp));
ll res=0;
for(int i=0;i<n;i++)
cin>>b[i];
ll s1=solve(0,0);
ll s2=solve(0,1);
cout<<max(s1,s2)<<"\n";
}
}

Princess Farida on Spoj

I stuck at a problem SPOJ.
I checked all the test cases passing all of them, but I am still getting "WA" on spoj.
I know it can be solved using dynamic programming, but I am practicing memoization.
Here is my code:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector <int> dp(1000000);
long long int maxloot(vector<int> &loot, int n) {
if (n == 0)
return 0;
if (n == 1)
return loot[0];
if (n == 2)
return max(loot[0], loot[1]);
if (dp[n] != -1)
return dp[n];
long long int take = loot[n - 1] + maxloot(loot, n - 2);
long long int leave = maxloot(loot, n - 1);
return dp[n]= max(take, leave);
}
int main() {
int t;
cin >> t;
int p = 1;
while (t--) {
int n;
cin >> n;
vector <int> loot;
for (int i = 0; i < n; i++) {
int temp;
cin >> temp;
loot.push_back(temp);
}
dp.assign(1000000, -1);
cout <<"Case "<<p<<": "<< maxloot(loot, n)<<endl;
p++;
dp.clear();
}
}
Test case 1:
5
1 2 3 4 5
Test case 2:
1
10
output 1:
9
output 2:
10
You are using wrong data type to store value in vector dp.
As the sum of coins can go up to (10^9*10^2=10^11) therefore int would not be able to store it .Try using long long int instead as it would not lead to overflow condition.
SAME CODE AS YOURS(using long long int got accepted):
USE: vector< long long int>dp(1000000)
ACCEPTED CODE:
#include<iostream>
#include<vector>
#include<algorithm>
#define ull unsigned long long
using namespace std;
vector <long long int> dp(1000000);
long long int maxloot(vector<int> &loot, int n) {
if (n == 0)
return 0;
if (n == 1)
return loot[0];
if (n == 2)
return max(loot[0], loot[1]);
if (dp[n] != -1)
return dp[n];
long long int take = loot[n - 1] + maxloot(loot, n - 2);
long long int leave = maxloot(loot, n - 1);
return dp[n]= max(take, leave);
}
int main() {
int t;
cin >> t;
int p = 1;
while (t--) {
int n;
cin >> n;
vector <int> loot;
for (int i = 0; i < n; i++) {
int temp;
cin >> temp;
loot.push_back(temp);
}
dp.assign(1000000, -1);
cout <<"Case "<<p<<": "<< maxloot(loot, n)<<endl;
p++;
dp.clear();
}
}

Non-Divisible Subset - Hackerrank

I am trying to solve the Non-Divisible Subset problem from Hackerrank (https://www.hackerrank.com/challenges/non-divisible-subset). I am trying to use the idea that if the sum of a and b is divisible by k, then a%k+b%k = k, however, it's not working very well.
Here is what I've written so far:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n;
int k;
cin >> n;
cin >> k;
int j;
vector<int>numbers;
vector<int>remainders;
for(int i = 0; i < n; i++) {
int z;
cin >> z;
numbers.push_back(z);
}
for (vector<int>::iterator it = numbers.begin(); it != numbers.end(); it++) {
j = *it % k;
remainders.push_back(j);
}
for(vector<int>::iterator it2 = remainders.begin(); it2 != remainders.end(); it2++) {
int remainderCount = 0;
int otherRemainderCount = 0;
otherRemainderCount = std::count(remainders.begin(), remainders.end(), k-*it2);
remainderCount = std::count(remainders.begin(), remainders.end(), *it2);
if (remainderCount > otherRemainderCount) {
theChosenOne = *it2;
} else if (otherRemainderCount > remainderCount) {
theChosenOne = k-*it2;
}
cout << theChosenOne << endl;
}
return 0;
}
I created a vector for the remainders and I am using the std::cout function to find out which remainder appears more in the vector. If K would be 5, *it2 = 4, and k-*it2 = 1. If *it2 appears more times, then I would choose *it2. Otherwise, I would choose k-*it2.
Your solution looks to be on the right track, but there is some change that is needed.
You basically need to hash the numbers in the array to proper location.
Have an array rem[k] initialised to 0.
Iterate over the n numbers in the array, and do the following:
rem[array[i]%k]++;
Now you have to deal with only the rem[] array, to find the maximum subset. The rem array has size of maximum k<=100. Make use of the small size of rem[] array to find the solution efficiently.
Edit: Adding the code for you.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n,i,k;
cin>>n>>k;
int arr[n];
int rem[k]={0};
for(i=0;i<n;i++)
{
cin>>arr[i];
}
for(i=0;i<n;i++)
{
rem[arr[i]%k]++;
}
int count = 0;
for(i=1;i<=k/2;i++)
{
count = count + max(rem[i],rem[k-i]);
}
count = count + (rem[0]>0?1:0);
if(k%2==0)
{
count = count - rem[k/2];
if(rem[k/2]>0)
count = count + 1;
}
cout<<count;
return 0;
}
After you have found out the contents of the rem[] array, its time to find the maximum subset. If you select rem[1] then you cannot select rem[k-1] as any two numbers, one from rem[1] and another from rem[k-1] can be summed together which will be divisible by k that we don't want. So we find whichever is maximum out of rem[i] and rem[k-i] and add it to the count
My code uses the above logic..
Hope it helps!!!
int main() {
int n,k;
cin>>n>>k;
vector <int> a(n);
vector <int> r(k,0);
for(int i=0;i<n;i++)
{
cin>>a[i];
r[a[i]%k]++;
}
int ctr=min(1,r[0]);
for(int a=1;a<(k/2+1);a++)
{
if(a!=k-a)
ctr+=max(r[a],r[k-a]);
}
if(k%2==0&&r[k/2]!=0)
ctr++;
cout<<ctr;
return 0;
}
This seemed to work
#include <stdio.h>
int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }
int main() {
int n, k, a, total = 0;
scanf("%d %d", &n, &k);
int mods[k];
for (int i = 0; i < k; i++)
mods[i] = 0;
while (n--) {
scanf("%d", &a);
mods[a % k]++;
}
// can only have 1 value congruent to 0 mod k
total += min(1, mods[0]);
// if even, can only have 1 value congruent to k/2 mod k
if (k % 2 == 0)
total += min(1, mods[k / 2]);
// for all others, pick max of those k and n-k mod k
for (int d = 1; d < (k + 1) / 2; d++) { // for all others,
total += max(mods[d], mods[k - d]);
}
printf("%d", total);
return 0;
}

Get the max element in an array that ends with a 0

So, I am writing a code which creates an array with an elements and amount of elements written by user and then a code generates a biggest value which last digit is zero. So, I have accomplished a step of writing an array which is elements entered by user. The hardest part( for me) is to complete a code which generates biggest value which last digit is zero. So yeah, I need an advice in completing this code. Thank you.
for example :
An array - 2 20 25 300 55555
The biggest number which last digit is zero is 300
So yeah, I need an advice in completing this code. Here is a code what I have done so far :
#include "stdafx.h"
#include <stdlib.h>
#include <windows.h>
#include <time.h>
int GetAmount() {
int howmany;
printf("Enter amount of elements - ");
scanf_s("%i", &howmany);
return howmany;
}
void GetArray(int a[], int n) {
printf("Enter elements - \n");
for (int i = 0; i < n; i++)
{ printf("%i ->", i);
scanf_s("%i", &a[i]);
}
}
int LastDigitZero(int n[], int a) {
for (int i = 0; i < a; i++)
{
if (n[i] % 10 == 0) {
return 0;
}
}
}
int maxvalue(int a[], int n) {
int temp = 0;
for (int i = 0; i < n; i++)
{
if (a[i] > temp) {
temp = a[i];
}
}
return temp;
}
void main() {
int amount = GetAmount();
int array[100];
GetArray(array, amount);
int max = maxvalue(array, amount);
printf("Max Value is %i\n", max);
}
Thank you for your attention, have a nice day! :)
It works! That's how it looks!
#include "stdafx.h"
#include <stdlib.h>
#include <windows.h>
#include <time.h>
int GetAmount() {
int howmany;
printf("Enter amount of elements - ");
scanf_s("%i", &howmany);
return howmany;
}
void GetArray(int a[], int n) {
printf("Enter elements - \n");
for (int i = 0; i < n; i++)
{ printf("%i ->", i);
scanf_s("%i", &a[i]);
}
}
int maxvalue(int a[], int n) {
int temp = 0;
for (int i = 0; i < n; i++)
{
if (a[i] % 10 == 0 && a[i] > temp) {
temp = a[i];
}
}
return temp;
}
void main() {
int amount = GetAmount();
int array[100];
GetArray(array, amount);
int max = maxvalue(array, amount);
printf("The biggest number which last digit is zero is %i\n ", max);
system("pause");
}
Thank you guys for the answers! That was fast!!! :)
You almost have it. First any number that ends in 0 mod 10 is 0 so that is how you can check if the last digit is 0. With that you would change maxvalue() to
int maxvalue(int a[], int n) {
int temp = a[0];
for (int i = 1; i < n; i++)
{
if (a[i] % 10 == 0 && a[i] > temp) {
temp = a[i];
}
}
return temp;
}
I also made a change to set temp to the value of a[0] as if your array is all negative numbers then 0 would be the largest number. Since temp is already a[0] we can then start the for loop at 1.
You should check if there is a solution, in this example you could check that the value returned by maxValue finishes by 0 (if none of the values finishes by 0 then it would return a[0]):
int maxValue(int a[], int n) {
int temp= a[0]
for (int i(1); i<n;i++) {
if (a[i] % 10 == 0 && (temp % 10 != 0 || a[i] > temp )) temp = a[i];
}
return temp;
}