SPOJ ETF c/c++ code - c++

I am doing a question in spoj http://www.spoj.com/problems/ETF/ . I submitted this code.
#include <iostream>
using namespace std;
int fi(int);
int main()
{
int t,n;
cin>>t;
while(t--)
{
cin>>n;
printf("%d\n",fi(n));
}
}
int fi(int n)
{
int result = n;
for(int i=2;i*i <= n;i++)
{
if (n % i == 0) result -= result / i;
while (n % i == 0) n /= i;
}
if (n > 1) result -= result / n;
return result;
}
ACCEPTED IN: 0.60 sec.
I want to know one thing
Why my code got accepted in c++4.3.2 while i was using a printf?

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";
}
}

Spit the array such that gcd(val[i],val[j])>1

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;
}

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();
}
}

Minimum difference in an array

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; }