I would to solve this problem illustrated in this image using C++
Define f(n) as the sum of the factorials of the digits of n. For example, f(342) = 3! + 4! + 2! = 32.
Define sf(n) as the sum of the digits of f(n). So sf(342) = 3 + 2 = 5.
Define g(i) to be the smallest positive integer n such that sf(n) = i. Though sf(342) is 5, sf(25) is also 5, and it can be verified that g(5) is 25.
Define sg(i) as the sum of the digits of g(i). So sg(5) = 2 + 5 = 7.
Further, it can be verified that g(20) is 267 and ∑ sg(i) for 1 ≤ i ≤ 20 is 156.
What is ∑ sg(i) for 1 ≤ i ≤ 150?
Image:
Here is my approach. My code takes long time running, and it works
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int factorial(int n);
std::vector<int> int_to_vector(int n);
int sum_vector(std::vector<int> v);
int get_smallest_number(std::vector<int> v, int sum, int n);
int sum_sg(int n )
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int q;
int m,n;
int g;
int sum = 0;
std::vector<int> vec;
cin>>q;
if( 1<=q && q<=100000){
std::vector<int> s;
int fact = 0;
int sg = 0;
for ( int i = 0; i < q; i++){
cin>>n>>m;
fact = factorial(n);
s = int_to_vector(fact);
sum = sum_vector(s);
g = get_smallest_number(s, sum, n);
s = int_to_vector(g);
sum = sum_vector(s);
}
}
return 0;
}
int factorial(int n){
if (n==0) return 1;
return factorial(n-1)*n;
}
std::vector<int> int_to_vector(int n){
std::vector<int> numbers;
while(n>0)
{
numbers.push_back(n%10);
n/=10;
}
return numbers;
}
int sum_vector(std::vector<int> v){
int sum=0;
for(int i = 0; i < v.size(); i++){
sum+=v.at(i);
}
return sum;
}
int get_smallest_number(std::vector<int> v, int sum, int n){
int i = 0;
int factoriel = 1;
std::vector<int> vect;
int sum2 = 0;
while( i < n){
factoriel = factorial(i);
vect = int_to_vector(factoriel);
sum2 = sum_vector(vect);
if( sum2 == sum) return i;
i++ ;
}
return n;
}
I think on recursive solutions, but it seems somehow more complex to implement. Are there any solutions using modern C++ and STL?
Here is below a bad solution with less complexity, please any suggestion to have good and fast code rather than this below,
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
std::vector<int> factorial {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
std::vector<int> int_to_vector(int n);
int sum_vector(std::vector<int> v);
int find_g(int i);
int calculat_sum_fact(std::vector<int> v);
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int m,n,q;
std::vector<int> vec;
std::vector<int> s;
std::vector<int> numbers;
cin>>q;
for (int i = 0; i < q; i++){
cin>>n>>m;
numbers.push_back(n);
// cout<< numbers.at(i);
}
for(int k = 0; k < numbers.size(); k++){
int sum = 0;
for (int i = 0; i < numbers.at(k)+1; i++){
s = int_to_vector(find_g(i));
sum += sum_vector(s);
}
cout << sum << "\n";
}
return 0;
}
std::vector<int> int_to_vector(int n){
std::vector<int> numbers;
while(n>0)
{
numbers.push_back(n%10);
n/=10;
}
return numbers;
}
int sum_vector(std::vector<int> v){
int sum=0;
for(int i = 0; i < v.size(); i++){
sum+=v.at(i);
}
return sum;
}
int find_g(int i){
std::vector<int> s ;
int sum = 0;
int j = 0;
//cout<<"sf 1= " << j << endl;
while(true){
s = int_to_vector(j);
sum = calculat_sum_fact(s);
s= int_to_vector(sum);
sum = sum_vector(s);
//cout<<"sf 2= " << j << endl;
if (sum == i) {
//cout<<"sf = " << j << endl;
return j;
//break;
}
//cout<<"sf = " << j << endl;
j++;
}
}
int calculat_sum_fact(std::vector<int> v){
int sum = 0;
for(int i = 0; i < v.size(); i++ ){
sum += factorial.at(v.at(i));
}
return sum;
}
Related
You have been given an array/list(ARR) of size N. You need to swap every pair of alternate elements in the array/list.
You don't need to print or return anything, just change in the input array itself.
#include <iostream>;
using namespace std;
void printArr(int arr[], int n)
{
for (int i = 0; i < n; i++)
cout << arr[i]<<i;
}
void UpdateArr(int arr[], int n)
{
int i = 0, j = n - 1;
while (i < j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i += 2;
j -= 2;
}
cout<<' printArr(arr[], n)';
}
int main()
{
int t;
cin>> t;
int n;
cin>> n;
int input[100];
for(int i=0; i<n; i++) {
cin >>input[i];
}
int arr[100] ;
n = sizeof(arr) / sizeof(arr[0]);
UpdateArr(arr, n);
return 0;
}
I'm not sure what are you exactly expecting the output to be (pls edit it and show the expected output) but I think this is what you need to do
#include <iostream>
#include <iomanip>
using namespace std;
void UpdateArray(int Arr[], size_t n) {
for (size_t i = 0; i < n / 2; i++) {
int Holder = Arr[i];
Arr[i] = Arr[~i + n];
Arr[~i + n] = Holder; } }
int main() {
int Arr[7] = { 1,2,3,4,5,6,7 };
UpdateArray(Arr, 7);
for (int i = 0; i < 7; i++) {
std::cout << Arr[i] << "\n"; }
return 0; }
size_t is like an int but it can't go into negative, but it can take bigger positive numbers, you can replace it with int, it shouldn't make a difference.
so we loop through half the array, replacing first items with last, the [~i + n] flips the value to the other side, so like index 4 in a array size of 20 will become 15
kadane's algorithm implementation
input = (t=1;n=3;arr={-1,4,5}) gives output 8 but expected output was 9.
#include <iostream>
#include<cmath>
using namespace std;
int Max( int *arr, int n){
int currmax = arr[0];
int globalmax = arr[0];
for(int i = 1; i < n; i++) {
currmax= max(currmax, currmax + arr[i]);
if(currmax > globalmax)
globalmax = currmax;
}
return globalmax;
}
int main() {
int t;
cin >> t;
while(t--){
int n;
cin >> n;
int arr[n];
for(int i = 0; i < n; i++) cin >> arr[i];
cout << Max(arr, n) << " ";
}
}
Change currmax= max(currmax, currmax+arr[i]) to currmax= max(arr[i], currmax+arr[i]) as to compare current value with array value.
In you case -1, 4, 5
Value of currmax will be updated as below:
1. currmax = -1, currmax+arr[1] = 3 (compare btw(4,3))
2. currmax= 4 , currmax+arr[2] = 9 (compare btw(5,9))
3. currmax = 9
Code Below:
#include <iostream>
#include <cmath>
using namespace std;
int Max( int *arr, int n){
int currmax=arr[0];
int globalmax=arr[0];
for(int i=1;i<n;i++) {
currmax= max(arr[i], currmax+arr[i]); // your code line was wrong here check and try
if(currmax>globalmax)
globalmax=currmax;
}
return globalmax;
}
int main() {
int t;
cin>>t;
while(t--){
int n;
cin>>n;
int arr[n];
for(int i=0;i<n;i++) cin>>arr[i];
cout<<Max(arr,n)<<" ";
}
}
Please find the correct Answer for Maximum SubArray (Kadane's Theorem)
C# Solution:
public int MaxSubArray(int[] nums) {
int maxSum = nums[0];
int currSum = 0;
for(int i = 0; i < nums.Length; i++){
currSum = currSum + nums[i];
if(maxSum < currSum){
maxSum = currSum;
}
if(currSum < 0){
currSum = 0;
}
}
return maxSum;
}
enter code here
so I am trying to implement the following pseudocode but it will not work as it is supposed to. Here is the problem description in the slide, "Given an integer bound, "W", and a collection of "n" items, each with a positive integer weight "wi", find a subset S of items that: maximizes Sigma sub i where i is an element of S "wi" while keeping this sum less than or equal or to W. I will attach the following slides for where I am getting the problem description and pseudocode from. The problem with my implementation is that it will only find the total max value and not the value that is less than or equal to the weight. So for example, if I had Weight 10 (W = 10) and items 3 (n = 3) with item weights 1, 4, & 8 then the following answer should be 9; however, my solution gives 12. Here are the slides (*Please not, where it says w[j] it is meant to be w[i] - the slide had a typo):
Here is my code that implements the pseudocode:
#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int max(int a, int b, int c) {
if (a >= b)
return a;
else
return b;
}
int optimal_weight(int W, const vector<int> &wt, int n){
vector<vector<int> > M;
M.resize(n+1);
for(int i = 0; i < n+1; ++i){
M[i].resize(W+1);
}
for(int w = 0; w < W+1; w++){
M[0][w] = 0;
}
for(int i = 1; i < n+1; i++){
M[i][0] = 0;
}
for(int i = 1; i < n+1; i++){
for(int w = 0; w < W+1; w++){
if(wt[i] > w){
M[i][w] = M[i-1][w];
}
M[i][w] = max(M[i-1][w], wt[i] + M[i-1][W-wt[i]], W);
}
}
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= W; j++)
printf ("%4d", M[i][j]);
printf("\n");
}
return M[n][W];
}
int main()
{
//int val[] = {1, 1, 1};
int W;
int n;
cin >> W >> n;
vector<int> wt(n);
for(int i = 0; i < n; i++){
cin >> wt[i];
}
cout << optimal_weight(W, wt, n) << endl;
}
Thank you for any help!
I figured it out! Here is my solution:
#include <iostream>
#include <vector>
using namespace std;
using std::vector;
int optimal_weight(int W, const vector<int> &wt) {
//write your code here
int n = wt.size();
vector<vector<int> > matrix;
matrix.resize(W+1);
for(int i = 0; i < W+1; i++){
matrix[i].resize(n);
}
for(int j = 0; j < n; j++){
matrix[0][j] = 0;
}
for(int w = 0; w < W + 1; w++){
matrix[w][0] = 0;
}
for(int i = 1; i < n; i++){
for(int w = 1; w < W+1; w++){
matrix[w][i] = matrix[w][i-1];
if(wt[i] <= w){
//cout << wt[i] << endl;
int val = matrix[w-wt[i]][i-1] + wt[i];
if(matrix[w][i] < val){
matrix[w][i] = val;
}
}
}
}
return matrix[W][n-1];
}
int main() {
int n, W;
std::cin >> W >> n;
vector<int> wt(n+1);
for (int i = 1; i < n+1; i++) {
wt[0]=0;
std::cin >> wt[i];
}
std::cout << optimal_weight(W, wt) << '\n';
}
The subarray contains both positive and negative numbers. You have to find a maximum sum subarray such that the length of the sub-array is greater than or equal to k.
Here is my code in c++ using Kadane's algorithm.
#include <iostream>
using namespace std;
int main(){
int n,k;
cin >> n >> k;
int array[n];
int sum = 0;
int maxsum = 0;
int beststarts[n];
for(int i = 0;i < n; i++){
cin >> array[i];
}
for(int i = 0;i < k-1;i ++){
sum = sum+array[i];
beststarts[i] = 0;
}
for(int i = k-1;i < n; i++){ //best end search with min length;
sum = sum+array[i];
int testsum = sum;
if(i > 0){
beststarts[i] = beststarts[i-1];
}
for(int j = beststarts[i] ;i-j > k-1;j ++){
testsum = testsum - array[j];
if(testsum > sum){
beststarts[i] = j+1;
sum = testsum;
}
}
if(sum > maxsum){
maxsum = sum;
}
}
cout << maxsum;
return 0;
}
My code is working fine but it is very slow, and i cant think of any ways to improve my code. I have also read this question Find longest subarray whose sum divisible by K but that is not what i want, the length can be greater than k also.
Solution based on this answer
Live demo
#include <algorithm>
#include <iterator>
#include <iostream>
#include <numeric>
#include <ostream>
#include <utility>
#include <vector>
// __________________________________________________
template<typename RandomAccessIterator> typename std::iterator_traits<RandomAccessIterator>::value_type
max_subarr_k(RandomAccessIterator first,RandomAccessIterator last,int k)
{
using namespace std;
typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
if(distance(first,last) < k)
return value_type(0);
RandomAccessIterator tail=first;
first+=k;
value_type window=accumulate(tail,first,value_type(0));
value_type max_sum=window, current_sum=window;
while(first!=last)
{
window += (*first)-(*tail) ;
current_sum = max( current_sum+(*first), window );
max_sum = max(max_sum,current_sum);
++first;
++tail;
}
return max_sum;
}
// __________________________________________________
template<typename E,int N>
E *end(E (&arr)[N])
{
return arr+N;
}
int main()
{
using namespace std;
int arr[]={1,2,4,-5,-4,-3,2,1,5,6,-20,1,1,1,1,1};
cout << max_subarr_k(arr,end(arr),4) << endl;
cout << max_subarr_k(arr,end(arr),5) << endl;
}
Output is:
14
11
int w(0);
for (int i=0; i < k; i++) w += a[i];
int run_sum(w), max_sum(w);
for (int i=k; i < n; i++) {
w = a[i] + max(w, w-a[i-k]); // window will such that it will include run_sum
run_sum = max(run_sum + a[i], w);
max_sum = max(run_sum, max_sum);
}
return max_sum;
The subarray contains both positive and negative numbers. You have to find a maximum sum subarray such that the length of the sub-array is greater than or equal to k.
Here is my code in c++ using Kadane's algorithm.
#include <iostream>
using namespace std;
int main(){
int n,k;
cin >> n >> k;
int array[n];
int sum = 0;
int maxsum = 0;
int beststarts[n];
for(int i = 0;i < n; i++){
cin >> array[i];
}
for(int i = 0;i < k-1;i ++){
sum = sum+array[i];
beststarts[i] = 0;
}
for(int i = k-1;i < n; i++){ //best end search with min length;
sum = sum+array[i];
int testsum = sum;
if(i > 0){
beststarts[i] = beststarts[i-1];
}
for(int j = beststarts[i] ;i-j > k-1;j ++){
testsum = testsum - array[j];
if(testsum > sum){
beststarts[i] = j+1;
sum = testsum;
}
}
if(sum > maxsum){
maxsum = sum;
}
}
cout << maxsum;
return 0;
}
My code is working fine but it is very slow, and i cant think of any ways to improve my code. I have also read this question Find longest subarray whose sum divisible by K but that is not what i want, the length can be greater than k also.
Solution based on this answer
Live demo
#include <algorithm>
#include <iterator>
#include <iostream>
#include <numeric>
#include <ostream>
#include <utility>
#include <vector>
// __________________________________________________
template<typename RandomAccessIterator> typename std::iterator_traits<RandomAccessIterator>::value_type
max_subarr_k(RandomAccessIterator first,RandomAccessIterator last,int k)
{
using namespace std;
typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
if(distance(first,last) < k)
return value_type(0);
RandomAccessIterator tail=first;
first+=k;
value_type window=accumulate(tail,first,value_type(0));
value_type max_sum=window, current_sum=window;
while(first!=last)
{
window += (*first)-(*tail) ;
current_sum = max( current_sum+(*first), window );
max_sum = max(max_sum,current_sum);
++first;
++tail;
}
return max_sum;
}
// __________________________________________________
template<typename E,int N>
E *end(E (&arr)[N])
{
return arr+N;
}
int main()
{
using namespace std;
int arr[]={1,2,4,-5,-4,-3,2,1,5,6,-20,1,1,1,1,1};
cout << max_subarr_k(arr,end(arr),4) << endl;
cout << max_subarr_k(arr,end(arr),5) << endl;
}
Output is:
14
11
int w(0);
for (int i=0; i < k; i++) w += a[i];
int run_sum(w), max_sum(w);
for (int i=k; i < n; i++) {
w = a[i] + max(w, w-a[i-k]); // window will such that it will include run_sum
run_sum = max(run_sum + a[i], w);
max_sum = max(run_sum, max_sum);
}
return max_sum;