I am working on a code to print all the numbers which have their LCM as 240. Now this is pretty easy, write 2 for loops and you're done. I have provided the code below. What I want now is to remove duplicate pairs. For example, if I have already printed (16,30) I dont want to print (30,16).
So what I have thought to resolve this is modify the 2nd indices to have an upper limit equal to the 1st index.
using namespace std;
int findLCM(int a, int b)
{
int lar = max(a, b);
int small = min(a, b);
for (int i = lar; ; i += lar) {
if (i % small == 0)
return i;
}
}
int main()
{
int a = 5, b = 7,s=0;
for(int i=1;i<=360;i++){
for(int j=1;j<=i;j++){
if(findLCM(i,j)==360){
cout<<"("<<i<<","<<j<<")"<<endl;
s++;
}
}
}
cout<<s;
return 0;
}
\\modified code
using namespace std;
{
int lar = max(a, b);
int small = min(a, b);
for (int i = lar; ; i += lar) {
if (i % small == 0)
return i;
}
}
int main()
{
int a = 5, b = 7,s=0;
for(int i=1;i<=240;i++){
for(int j=1;j<=i;j++){
if(findLCM(i,j)==240){
cout<<"("<<i<<","<<j<<")"<<endl;
s++;
}
}
}
cout<<s;
return 0;
}
So I found that this does seem to work. Is this modification in the loop enough to ensure that duplicate pairs aren't printed?
Related
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;
}
I wrote the code with o(n^2) complexity.I could not find the error.My idea was to first sort the array and then starting from the first element if the second next is equal increment i by 2 and when the if condition is not fulfilled the element is found Can someone please help me this.
Thanks in advance
#include<iostream>
using namespace std;
int main()
{
int arr[100];
int n,i,j,temp;
cin>>n;
for(i=0;i<n;i++)
{
cin>>arr[i];
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(arr[i]>arr[j])
{
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
i=0;
for(j=i+1;j<n;j++)
{
if(arr[i] == arr[j])
{
i=i+2;
}
}
cout<<arr[i];
return 0;
}
To find a non-repetitive element in an array the first thing that comes to mind is that if we first sort the array and then try to manipulate it. The sorting process is easy and as follows:
int arr[] = {/*Some array*/};
int arrSize = sizeof(arr)/sizeof(int);
//Lets sort the array
for(int i=0;i<arrSize;i++)
{
for(int j=i;j<arrSize;j++)
{
if(arr[i]>arr[j])
{
int t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
}
After sorting the array we may see different scenarios like:
int arr1[] = {1,1,2,2,3};
int arr2[] = {1,2,2,3,3};
int arr3[] = {1,1,2,3,3};
We have to design an algorithm such that it can differentiate and easily manipulate the three scenarios. Let n be our number. The first scenario is to check if the last isn't the same as the previous one by:
if(arr[arrSize-1] != arr[arrSize-2]) //The last is not the same as the previous
{
n=arr[arrSize-1];
}
The second one is similar to the first:
if(arr[0] != arr[1]) // The first element is not the same as the second
{
n = arr[0];
}
The third one is easy too, we just have to check if two neighbors are never equal to the middle number, this is as follows:
for(int i=1;i<arrSize-1;i++)
{
if(arr[i-1] != arr[i] && arr[i] != arr[i+1])
{
n=arr[i];
break;
}
}
And so the full code would become:
#include <iostream>
using namespace std;
int main()
{
int arr[] = {1,2,3,4,2,3,1};
int arrSize = sizeof(arr)/sizeof(int);
//Lets sort the array
for(int i=0;i<arrSize;i++)
{
for(int j=i;j<arrSize;j++)
{
if(arr[i]>arr[j])
{
int t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
}
int n;
if(arr[0] != arr[1]) // The first element is not the same as the second
{
n = arr[0];
}
else if(arr[arrSize-1] != arr[arrSize-2]) //The last is not the same as the previous
{
n=arr[arrSize-1];
}
else //Lets search for a number such that its not the same as the numbers on the left and on the right
{
for(int i=1;i<arrSize-1;i++)
{
if(arr[i-1] != arr[i] && arr[i] != arr[i+1])
{
n=arr[i];
break;
}
}
}
cout << n;
}
The Second Way (Better one).
Here's another way we could solve this problem. Suppose that I have a number n=3, if i XORed it with 3 i will get 0, so if we have an array lets say arr[] = {1,2,1}, I first assign n=0, then XOR it with the firs element (1), next I XOR n with the second element and then with the third element. What will happen? The third XOR will cancel the effect of the first thus n will equal to 1. Sample Code:
#include <iostream>
using namespace std;
int main()
{
int arr[] = {1,2,3,4,2,3,1};
int arrSize = sizeof(arr)/sizeof(int);
int n=0;
for(int i=0;i<arrSize;i++)
{
n^=arr[i];
}
cout << n;
}
This code is O(n).
Use XOR. XOR of all array elements gives us the number with a single occurrence.
#include <bits/stdc++.h>
using namespace std;
int singleoccurence(int arr[], int n)
{
int res = arr[0];
for (int i = 1; i < n; i++)
{
res = res ^ arr[i];
}
return res;
}
int main()
{
int arr[] = {7, 3, 5, 4, 5, 3, 4};
int n = sizeof(arr) / sizeof(arr[0]);
int val = singleoccurence(arr, n);
cout << "ELEMENT OCCURING ONLY ONCE IS :" << val;
}
Solution in C#
public static int lonelyinteger(List<int> a)
{
int lonely = 0;
foreach(var item in a)
{
List<int> listTemp = a.Where(x => x == item).ToList();
if(listTemp.Count == 1)
lonely = listTemp.FirstOrDefault();
}
return lonely;
}
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;
}
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 have a function which intends to see if two arrays contain similar elements.
This is the main function:
int arr[] = {1, 2, 2};
int arrb[] = {1, 2, 1};
int a = (sizeof(arr)/sizeof(arr[0]));
int b = (sizeof(arrb)/sizeof(arrb[0]));
cout << checkForSimilar(arr,arrb,a,b);
and the following function:
int checkForSimilar(int arraya[], int arrayb[], int a, int b)
{
if (a != b) return 0; else
{
int foundSwitch = 0;
int found = 0;
for (int i = 0; i < a; i++)
{
for (int j = 0; j < b; j++)
{
if (arraya[i] == arrayb[j])
{
foundSwitch = 1;
break;
} else foundSwitch = 0;
}
}
return foundSwitch;
}
}
The function is not returning expected values, however. In the above example, for example, it should return 0, but it returns 1. This function returns the correct value for some arrays and not the correct one for others. I don't understand what I am doing wrong here.
EDIT: I worded the above function poorly. It's an equality test, where both arrays need to contain the same elements. However, they don't have to be in the same order.
The simplest and more efficient is to sort before comparing (n log n vs n²):
bool checkForSimilar(int arraya[], int arrayb[], int a, int b)
{
std::sort(arraya, arraya + a);
std::sort(arrayb, arrayb + b);
return a == b && std::equal(arraya, arraya + a, arrayb);
}
Demo
First off the code breaks when it finds one similarity. If you want to check if both arrays have the same elements (and in the same position), you might want to change it like this:
if (a != b)
return 0;
else
{
int foundSwitch = 0;
int found = 0;
for (int i = 0; i < a; i++)
{
if (arraya[i] != arrayb[i])
{
foundSwitch = 0;
break;
}
else foundSwitch = 1;
}
return foundSwitch;
}
This code will only work if both the elements and their order are the same (ex. {3, 2, 1} and {1, 2, 3} will return 0).
You can use a for loop if you don't care about order.
if (a != b)
return 0;
else
{
int foundSwitch;
int numToCheck;
for (int i = 0; i < a; i++)
{
numToCheck = arraya[i];
foundSwitch = 0;
for (int j = 0; j < b; j++)
{
if (numToCheck == arrayb[j])
{
foundSwitch = 1;
break;
}
}
if (foundSwitch == 0)
break;
}
return foundSwitch;
}
Basically this checks the i element in arrayA. If that element is in arrayB then in breaks the inner j loop and sets found switch to 1. By default its gonna be 0 so if it goes unchanged by the time the j loop ends then you found an element that is in array a that is not in b.
your code must be:
`int checkForSimilar(int arraya[], int arrayb[], int a, int b)
{
if (a != b) return 0; else
{
int foundSwitch = 1;
int found = 0;
for (int i = 0; i < a; i++)
{
for (int j = 0; j < b; j++)
{
if (arraya[i] == arrayb[j])
{
foundSwitch = 0;
break;
}
}
if(foundSwitch == 0){
break;
}
}
return foundSwitch;
}
}`
The function you wrote says the two arrays are similar because you're simply checking if each of the elements in the first array exist in the second array. In the test example you've put here, it is the case so you're getting 1 as a return.
Since you want each element in an array to match with exactly one element of the other you should do it like this:
int foundSwitch = 0;
int found = 0;
for (int i = 0; i < a; i++)
{
for (int j = i; j < b; j++)
{
if (arraya[i] == arrayb[j])
{
foundSwitch = 1;
int temp = arrayb[i];
arrayb[i]=arrayb[j];
arrayb[j]=temp;
break;
} else foundSwitch = 0;
}
}
free[] foundvalues;
return foundSwitch;
As I commented above, you are just checking the existence of elements of one array in another one. Its would fail e.g. for [1,1,2,2] and [1,2,1,1] The simplest way would be to sort the two arrays first and then compare their elements one by one
int compare_int( const void* a, const void* b )
{
if( *(int*)a == *(int*)b ) return 0;
return *(int*)a < *(int*)b ? -1 : 1;
}
int checkForSimilar(int arraya[], int arrayb[], int a, int b)
{
if (a != b) {
return 0;
}
qsort(arraya, a, sizeof(int), compare_int); // O(n logn)
qsort(arrayb, b, sizeof(int), compare_int); // O(n logn)
for (int index = 0; index < a; ++index) { // O(n)
if (arraya[index] != arrayb[index]) {
return 0;
}
}
return 1;
}
Even complexity-wise its O(nlogn), so better than nested for loops which would be O(n2).
EDIT : Using std::sort as suggested by PaulMcKenzie
int checkForSimilar(int arraya[], int arrayb[], int a, int b)
{
if (a != b) {
return 0;
}
std::sort(std::begin(arraya), std::end(arraya));
std::sort(std::begin(arrayb), std::end(arrayb));
for (int index = 0; index < a; ++index) {
if (arraya[index] != arrayb[index]) {
return 0;
}
}
return 1;
}
A probably more efficient way is to use STL algorithms.
As an example below which copies the arrays to prevent that the originals get edited, then using std::sort to sort before checking for std::equal
bool isSimilar(int arr[], const int& size1, int arr2[], const int& size2)
{
int temp1[size1];
int temp2[size2];
copy(arr, arr + size1, temp1); // copy values into temps to avoid
copy(arr2, arr2 + size2, temp2); // editing to the originals
sort(temp1, temp1 + size1); // Sort for performance
sort(temp2, temp2 + size2);
if (equal(temp1, temp1 + size1, temp2))
return 1;
else
return 0;
}
int main()
{
int arr[] {1,2,3,4,5,6,7,8,9};
int arr2[] {9,8,7,6,5,4,3,2,1};
const int size1 = (sizeof(arr)/sizeof(*arr));
const int size2 = (sizeof(arr2)/sizeof(*arr2));
cout << (isSimilar(arr, size1, arr2, size2) ? "Similar" : "Not similar");
}
When the function returns, the original elements remain unmodified.
This code is not only is faster but it improves readability and looks more elegant.