It is good array only if gcd(val[i],val[j])>1
Here,
gcd(a,b) = Greatest common divisor of two numbers.
Split the array has one parameter
Val: A integer array of n integer
Here are two examples.
Sample Input 0:
5 // no of value in an integer
2
3
2
3
3
Sample Output 0:
2
Sample Input 1:
5 //no of value in an integer
3
5
7
11
2
Sample Output 1:
5
example of sample input 0
subarray[1..3] ={2,3,2} here gcd(2,2)>1
subarray[4..5]={3,3} gcd(3,3)>1
#include <bits/stdc++.h>
using namespace std;
string ltrim(const string &);
string rtrim(const string &);
Now how to impelement the splitTheArray() function?
You need to find the minimum number of subarrays such that in each sub-array, first and last elements' gcd > 1. You can do it easily by O(Nˆ2) complexity.
int splitTheArray(vector<int> val) {
// implement this function
int sz = val.size();
if(sz == 0) return 0;
int ind = sz - 1;
int subarray = 0;
while(ind >= 0) {
for(int i = 0; i <= ind; i++) {
if(__gcd(val[ind], val[i]) > 1) {
subarray++;
ind = i-1;
break;
}
}
}
return subarray;
}
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
int gcd(int a, int b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
int max(int a, int b)
{
return (a > b) ? a : b;
}
int min(int a, int b)
{
return (a < b) ? a : b;
}
int solve(vector<int> vec)
{
int n = gcd(vec[0], vec[vec.size() - 1]);
if (n > 1)
return 0;
int con = 0 , flag = 0 , j=0 , i=0 , flag2=0;
for (i = j; i < vec.size()/2; i++)
{
i = j;
if (i >= vec.size())
break;
int f = vec[i];
flag = 0;
for (j = i+1; j < vec.size(); j++)
{
int l = vec[j];
int ma = max(f, l);
int mi = min(f, l);
n = gcd(ma, mi);
if (flag)
{
if (n > 1)
con++;
else
break;
}
if (n > 1)
{
flag = 1;
flag2 = 1;
con++;
}
}
}
if (!flag2)
return vec.size();
return con;
}
int main()
{
int n;
cin >> n;
vector<int> vec;
for (int i = 0; i < n; i++)
{
int tm;
cin >> tm;
vec.emplace_back(tm);
}
cout<<solve(vec);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define int long long int
#define boost ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
void solve()
{
int n,i,j;
cin>>n;
int A[n+1],DP[n+1];
for(i=1;i<=n;i++)
cin>>A[i];
memset(DP,0,sizeof(DP));
unordered_map<int,int> M;
for(i=1;i<=n;i++)
{
vector<int> Fact;
Fact.push_back(A[i]);
for(j=2;j*j<=A[i];j++)
{
if(A[i]%j==0)
{
if(j*j==A[i])
{
Fact.push_back(j);
}
else
{
Fact.push_back(j);
Fact.push_back(A[i]/j);
}
}
}
int ans=DP[i-1]+1;
for(j=0;j<Fact.size();j++)
{
if(M.find(Fact[j])==M.end())
{
M[Fact[j]]=DP[i-1];
}
else
{
ans=min(ans,M[Fact[j]]+1);
}
}
DP[i]=ans;
}
cout<<DP[n]<<endl;
}
int32_t main()
{
boost;
int t=1;
// cin>>t;
for(int i=1;i<=t;i++)
{
//cout<<"Case #"<<i<<": ";
solve();
}
}
Time Complexity: N*Sqrt(max(A[i]))
P.S There can be a optimization of calculation of factor using the sieve instead of calculating factor every time for every number.
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
vector<int>a(n);
for(int i=0;i<n;i++){
cin>>a[i];
}
vector<int>dp(n+1,0);
dp[n-1]=1;
for(int i=n-2;i>=0;i--){
dp[i]=1+dp[i+1];
for(int j=i+1;j<n;j++){
if(__gcd(a[i],a[j])>1)
dp[i]=min(dp[i],1+dp[j+1]);
}
}
cout<<dp[0];
return 0;
}
Related
I have written a cpp code for array rotation and the file handling part is a bit tricky for me.
The code itself is correct but even though the files are in the same directory as the code it is not working for some reason
#include <math.h>
#include <algorithm>
#include <bits/stdc++.h>
#include <iostream>
#include <fstream>
using namespace std;
int ar[100];
// #define crap ios_base::sync_with_stdio(false);cin.tie(NULL);
int gcd(int a, int b)
{
if (b == 0)
return a;
else
return gcd(b, a % b);
}
void leftRotate(int arr[], int d, int n)
{
d = d % n;
int g_c_d = gcd(d, n);
for (int i = 0; i < g_c_d; i++) {
int temp = arr[i];
int j = i;
while (1) {
int k = j + d;
if (k >= n)
k = k - n;
if (k == i)
break;
arr[j] = arr[k];
j = k;
}
arr[j] = temp;
}
}
//int *func(int m)
//{
// int *p;
// p=new int[m];
// return (p);
//}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
// crap;
int n,d;
cin>>n>>d;
// ar=func(n);
// cout<<sizeof(ar);
for (int i=0;i<n;i++)
{
cin>>ar[i];
}
leftRotate(ar, d, n);
for (int i = 0; i < n; i++)
cout << ar[i] << " ";
return 0;
}
The code itself is working and returning correct output in the terminal but I cant seem to find the issue here
I have tried without file handling and it was giving a return value 3221225620 at the terminal
sample input is:
5 2
1 2 3 4 5
here shows a possible error:
3221225620 (0xC0000094): Zero Division Error
means that a divisor in your code could sometime be zero.
as for your code(line 20: d = d % n;), when your n is 0, the output will show return value 3221225620
so please check your data in "input.txt"
This is Project Euler question 26.
I would like to save the abundant values in an array, assuming there are no more than 200 abundant numbers smaller than 28123, which is the upper limit provided in the question.
This is not the complete code, but my program stops defining values at abundantarr[200]. Why am I seeing a limit to the values in this array?
#include <iostream>
#include <cmath>
using namespace std;
bool IsitAbundant(int a);
int main()
{
int abundantarr[200] = {0};
int counter = 0;
int totalsum = 0;
for (int u = 1; u < 28123; u++)
{
if (IsitAbundant(u))
{
abundantarr[counter] = u;
cout << abundantarr[counter] << endl;
counter++;
}
}
return 0;
}
bool IsitAbundant (int a)
{
int sum = 0;
for (int i = 1; i < a; i++)
{
if (a % i == 0)
{
sum+= i;
}
}
if (sum > a)
{
return true;
}
else
{
return false;
}
}
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;
}
I have the graph with N nodes. I have to create the longest subgraph (with max nodes). One node can be connected with only 2 nodes. So which nodes should I take to create this (max) subgraph?
What I'm doing is:
1: From initial node. I start 2 DFS functions. (from anothers nodes only 1).
2: For some node in DFS I use F() function to check all neighbours and find maximum way that I have to go. Then I'm saving the index of the node in which I have to go in index variable and starting DFS from index.
The problem is that this algorithm is too slow. How can I optimize it? Maybe there is special algorithm to find maximum subgraph?
Here is my code:
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
int used[20];
int m[20][20];
int c;
int F(int v) {
used[v] = 1;
int maxn = 0, index = -1, t;
for(int i = 0; i < c; ++i) {
if(!used[i] && m[v][i] == 1) {
t = F(i);
if(t > maxn) {
maxn = t;
index = i;
}
}
}
if(index != -1) {
used[v] = 0;
return maxn + 1;
}
else {
used[v] = 0;
return 1;
}
}
int DFS(int v) {
used[v] = 1;
int maxn = 0, index = -1, t;
for(int i = 0; i < c; ++i) {
if(!used[i] && m[v][i] == 1) {
t = F(i);
if(t > maxn) {
maxn = t;
index = i;
}
}
}
if(index != -1) {
return DFS(index) + 1;
}
else {
return 0;
}
}
int main() {
cin >> c;
for(int i = 0; i < c; ++i) {
for(int j = 0; j < c; ++ j)
cin >> m[i][j];
}
int maxn = DFS(0) + DFS(0) + 1;
cout << maxn << endl;
}
After reading through the theory of Merge Sort on TopCoder, I tried to write it's implementations, but it's getting weird, and I'm more or less a beginner in programming, especially algorithms. Can somebody assist me?
#include <iostream>
using namespace std;
int arr[] = {2, 0, 43, 12, 98};
int sizeOfarr(int a[])
{
return sizeof(a)/sizeof(a[0]);
}
int minElement(int x, int y)
{
if (x > y)
{
return y;
}
else if (x < y)
{
return x;
}
else
{
return x, y;
}
}
int main()
{
int t, z;
int n = sizeOfarr(arr);
int finalList[n];
int list1[n];
int list2[n];
for(int i = 0; i<=((n/2)-1); i++)
{
list1[i] = arr[i];
}
for(int j = n/2; j<n; j++)
{
for(int k = 0; k<=((n/2)-1); k++ )
{
list2[k] = arr[j];
}
}
for(int y = 0; y<=n; y++)
{
while(sizeOfarr(finalList)!=n)
{
t = list1[0];
z = list2[0];
finalList[y] = minElement(t, z);
if(finalList[y]==t)
{
list1[0] = list1[1];
}
else if(finalList[y]==z)
{
list2[0] = list2[1];
}
else
{
list1[0] = list1[1];
list2[0] = list2[1];
}
}
}
cout << "The sorted list is: " << finalList << endl;
return 0;
}
#include <iostream>
#include <math.h>
#include <string.h>
using namespace std;
int temp[10000];
void merge(int *A,int low,int mid,int high)
{
int i=low;
int j=mid+1;
int k=low;
int l;
while(i<=mid && j<=high)
{
if(A[i]<A[j])
{
temp[k]=A[i];
i=i+1;
}
else
{
temp[k]=A[j];
j=j+1;
}
k++;
}
for(l=i;l<=mid;l++,k++)
{
temp[k]=A[l];
}
for(l=j;l<=high;l++,k++)
{
temp[k]=A[l];
}
memcpy(A,temp,sizeof(A[0])*k);
}
void mergeSort(int *A,int low,int high)
{
int mid;
if(low<high)
{
mid=floor((low+high)/2);
mergeSort(A,low,mid);
mergeSort(A,mid+1,high);
merge(A,low,mid,high);
}
}
int main(int argc,char *argv[])
{
int n;
int array[10000];
cout<<"please enter the number numbers\n";
cin>>n;
cout<<"please enter the nubers\n";
for(int i=0;i<n;i++)
{
cin>>array[i];
}
mergeSort(array,0,n-1);
for(int i=0;i<n;i++)
{
cout<<array[i]<<" ";
}
cout<<"\n";
}
This is my implementation
mergeSort function divide recursively at middle and repeats until low lt(less than) high then a merge function is called.
I see from your code that the operator "," (return x,y) would replace x value by y value.
A few comments on the code:
return x,y // this just returns y. this is the case when x==y so it probably is OK bit not what one would write.
while(sizeOfarr(finalList)!=n) // The size of your array finalist is n elements. This is never going to change so this while condition is always false and the loop will never execute.