You can find the problem statement here.
My solution can be found here. I am getting correct answers for the test cases but the judge is indicating all answers wrong. What is wrong with my code?
#include <iostream>
#include <vector>
#include <map>
#include <math.h>
using namespace std;
map<long long,long long> arr;
void preProcess();
long long powerOfThree(long long num);
long long powerOfTwo(long long num);
long long theta(long long num);
int main()
{
preProcess();
long long t,k;
cin>>t;
while(t--)
{
cin>>k;
cout<<theta(k)<<endl;
}
}
void preProcess()
{
arr.insert(pair<long long,long long>(0,0));//arr[0]=0;
arr.insert(pair<long long,long long>(1,0));//arr[1]=0;
arr.insert(pair<long long,long long>(2,1));//arr[2]=1;
arr.insert(pair<long long,long long>(3,1));//arr[3]=1;
//arr.insert(pair<long long,long long>(4,2));//arr[4]=2;
//arr.insert(pair<long long,long long>(5,3));//arr[5]=3;
}
long long powerOfTwo(long long num)
{
long long ret=0;
while(num%2==0)
{
ret++;
num = num/2;
}
return ret;
}
long long theta(long long num)
{
long long ret;
map<long long,long long>::iterator it = arr.find(num);
if(it != arr.end())
{
return arr[num];
}
else
{
if(num%2==0)
{
long long a = powerOfTwo(num);
long long q = (num/(long long)pow(2,a));
ret = a + theta(q);
}
else if(num%3==0)
{
long long a = powerOfThree(num);
long long q = (num/(long long)pow(3,a));
ret = a + theta(q);
}
else
{
ret = 1 + theta(num-1);
}
}
arr.insert(pair<long long,long long>(num,ret));//arr[num]=ret;
return ret;
}
long long powerOfThree(long long num)
{
long long ret=0;
while(num%3==0)
{
ret++;
num = num/3;
}
return ret;
}
My approach is to first count all the powers of 2 and 3 in number and then reduce the result by 1. Again repeat the process till it is 1.
your method will fail in a number say for eg (2^8 + 1) *3^2. There would infact be many such numbers.
I would give a solution in Python(bcoz thats what I am comfortable in):
step = [0,0,1,1]
def find(a):
global step
t = len(step)
for n in range(t,a+1):
if ((n%3 == 0) and (n%2 == 0)):
step.append( 1 + min(step[n-1],step[n/2],step[n/3]))
elif (n%2==0):
step.append( 1 + min(step[n-1],step[n/2]))
elif (n%3 == 0) :
step.append( 1 + min(step[n-1],step[n/3]))
else :
step.append( 1 + step[n-1])
return step[a]
n = int(raw_input())
arr = []
for a in range(0,n):
arr.append(raw_input())
for st in arr:
n = int(st)
print find(n)
Related
You have N different balls numbered from 1 to N, and M different boxes numbered from 1 to M.
Input:
First line of input contains the number of test cases T. After that, next T lines contain the value of N and M.
Output:
For each test case, print the answer. As it can be very large, you should print it modulo 10^9 + 7.
I tried the below code, but it gives an error:
#include<iostream>
#include<cmath>
#include<math.h>
using namespace std;
int main()
{
unsigned short int T;
unsigned long int N,M;
cin>>T;
for (int i = 0; i < T; i++)
{
cin>>N>>M;
long int res;
res= pow(M,N);
int c=0;
c=pow(10,9);
res=res%(c + 7);
cout<<res<<endl;
}
return 0;
}
You must be facing integer overflow problem, that's why you must have been getting wrong answer.
Do the following steps to fix this problem.
change the unsigned long to long long or unsigned long long. (Why? Think).
Use the logarithmic user-defined function to calculate the value of the res = pow(M,N) along with the modulo consideration side-by-side. This will boost up your program.
See my code snippet to check what changes to be made:
#include<iostream>
#define MOD 1000000007
int main() {
unsigned short int T;
unsigned long long N , M , result;
unsigned long long power(unsigned long long, unsigned long long); /*prototype of power*/
std::cin>>T;
for (int i = 0; i < T; i++) {
std::cin >> N >> M;
result = power(M , N);
std::cout << result << std::endl;
}
return 0;
}
unsigned long long power(unsigned long long M, unsigned long long N) {
if(N == 0) {
return 1;
}
unsigned long long result = power(M , N/2);
result = (result * result) % MOD;
if(N%2 == 1) {
result = (result * M) % MOD;
}
return result;
}
I wrote the following code which gives an error;
ipt.cpp: In function ‘bool isprimet(long unsigned int, int)’:
ipt.cpp:28:86: error: no match for call to ‘(std::thread) (void (&)(long unsigned int, long unsigned int, long unsigned int, bool), const long unsigned int&, long unsigned int&, long unsigned int&, unsigned int&)’
for (unsigned long c=0;c
What am I doing wrong?
#include <iostream>
#include <thread>
#include <math.h>
using namespace std;
void ipt(const unsigned long number, const unsigned long root, const unsigned long threadid, bool &result)
{
result=true;
for (unsigned long c=5+threadid*6;c<=root;c+=(threadid+1)*6)
{
if(number % c-1 == 0) {result=false; break;};
if(number % c+1 == 0) {result=false; break;};
}
}
bool isprimet(const unsigned long number, const int nthreads)
{
if (number > 1)
{
if (number > 3)
{
if (number % 2 == 0) return false;
if (number % 3 == 0) return false;
unsigned int results[nthreads];
unsigned long root=(unsigned long)floor(sqrt(number))+1;
thread t[nthreads];
for (unsigned long c=0;c<nthreads;c++) t[c](ipt, number, root, c, results[c]);
for (unsigned long c=0;c<nthreads;c++) t[c].join();
for (unsigned long c=0;c<nthreads;c++) if (results[c]==false) return false;
return true;
}
else return true;
}
else return false;
}
When using std::thread, you need to send a callable object to the constructor of std::thread, and you can use Lambda expressions for this:
t[c] = new thread([&](){ ipt(number, root, c, results[c]); });
The following code works:
#include <thread>
#include <math.h>
#include <iostream>
using namespace std;
static int const MAX_THREADS = 128;
void ipt(const unsigned long number, const unsigned long root, const unsigned long threadid, bool &result)
{
result = true;
for (unsigned long c = 5 + threadid * 6; c <= root; c += (threadid + 1) * 6)
{
if (number % c - 1 == 0) { result = false; break; };
if (number % c + 1 == 0) { result = false; break; };
}
}
bool isprimet(const unsigned long number, const unsigned long nthreads)
{
if (number > 1)
{
if (number > 3)
{
if (number % 2 == 0) return false;
if (number % 3 == 0) return false;
bool results[MAX_THREADS];
unsigned long root = (unsigned long)floor(sqrt(number)) + 1;
thread* t[MAX_THREADS];
for (unsigned long c = 0; c < nthreads; c++)
t[c] = new thread([&](){ ipt(number, root, c, results[c]); });
for (unsigned long c = 0; c < nthreads; c++) {
t[c]->join();
delete t[c];
}
for (unsigned long c = 0; c < nthreads; c++)
if (results[c] == false)
return false;
return true;
}
else return true;
}
else return false;
}
int main(int argc, char *argv[])
{
for (int i = 1; i < 100; ++i)
if (isprimet(i,5))
cout << i << "\n";
return 0;
}
There are two problems with your code, they both occur in this line:
for (unsigned long c=0;c<nthreads;c++) t[c](ipt, number, root, c, results[c]);
which should look like this:
for (unsigned long c=0;c<nthreads;c++) t[c] = std::thread(ipt, number, root, c, std::ref(results[c]));
The first problem is the way that you are calling the function -- you can use the assignment operator as I have shown above.
Secondly, the default way that arguments are passed to a thread is by value. However, your function prototype specifies that you want to pass results[c] by reference, so you need to explicitly state that using std::ref(results[c]).
Also, you set the size of a static array with a non-const variable (so the compiler doesn't know the size at compile-time), hence all the compiler warnings. You need to use a constant to set the size, or define a global constant and use that, or pass the number of threads as a template argument, which will get rid of the compiler warnings.
Here is a live demo to a working example without warnings.
I have to generate the n-th fibonacci number from the first (zero-th) number being a and second being b. Below is my code for calculating this. I have been using matrix exponentiation method:
But the solution is wrong.
costum input:509618737 460201239 229176339(in order a,b,n)a=zeroth value,b=first value,n=Nth value to be found.
output:995159166
correct output:945141656
What is the problem with my code?
#include<iostream>
using namespace std;
void multiply(long long F[2][2], long long M[2][2]);//prototype of function multiplying 2 matrices.
void power(long long F[2][2],long long n);//prototype for incresing power
long long fib(long long n,long long a,long long b)//function that returns result as answer modulo 10^9+7(since answer is too long).
{
long long F[2][2] = {{1,1},{1,0}};
if (n == 0)
return a;
else if(n==1)
return b;
else if(n>1)
power(F, n-1);
return (F[0][0]*a+F[0][1]*b)%1000000007;//here's where i am confused ,whether i should multyply a first or b first i.e.f[0][0]*a+f[0][1]*b or f[0][0]*b+f[0][1]*a.plz explain this point too.
}
void power(long long F[2][2], long long n)
{
if( n == 0 || n == 1)
return;
long long M[2][2] = {{1,1},{1,0}};
power(F, n/2);
multiply(F, F);
if (n%2 != 0)
multiply(F, M);
}
void multiply(long long F[2][2], long long M[2][2])//matrices multiplied.
{
long long x = F[0][0]*M[0][0] + F[0][1]*M[1][0];
long long y = F[0][0]*M[0][1] + F[0][1]*M[1][1];
long long z = F[1][0]*M[0][0] + F[1][1]*M[1][0];
long long w = F[1][0]*M[0][1] + F[1][1]*M[1][1];
F[0][0] = x;
F[0][1] = y;
F[1][0] = z;
F[1][1] = w;
}
int main()
{
long long t, a, b, n, ans;
cin>>t;//# of test cases
while(t--)
{
cin>>a;//zeroth value
cin>>b;//first value
cin>>n;//Nth fibonaaci no. to be generated
ans=fib(n,a,b);//value of Nth no.
cout<<ans<<"\n";
}
return 0;
}
How to find count of numbers between a and b (inclusive) which contains 0 as their digit. I am not able to get this with the idea which i have used below in my code, it becomes very complex in case of leading zeroes
for ex if a=1 and b=200 total number should be 29 but i am getting 39.
Can anyone suggest an efficient way of doing it?
constraints:
1<=a<=b<=10^17
code:
long long int F(long long int dig, long long int a, long long int num)
{
if(dig == 0) {
if(a>0)
return 1;
else
return 0;
}
if(mem[dig][a])
return D[dig][a];
mem[dig][a] = 1;
long long int ret = 0;
for(long long int i = 0;i<=9;i++) {
if(i==num)
ret=(ret+F(dig-1,a+1,num));
else
ret=(ret+F(dig-1,a,num));
}
D[dig][a] = ret;
return ret;
}
long long int solve(long long int x,long long int num)
{
char cad[100];
long long int ret = 0;
long long int a=0,b=0,c=0,j;
sprintf(cad,"%lld",x);
int len = strlen(cad);
long long int qued = len;
for(long long int i = 0;i < len;i++) {
qued--;
long long int d = cad[i] - '0';
for(j=0;j <d;j++) {
if(j==num) {
if(num==0 && i==0)
a=a+0;
else
a=a+1;
ret=(ret+F(qued,a,num));
}
else
ret=(ret+F(qued,a,num));
}
if(d==num)
a=a+1;
}
return ret;
}
solution is -> solve(b+1,0)-solve(a,0)
but i am getting wrong answer with this
the link from which i got the above idea is http://codeforces.com/blog/entry/8221
A Simple way to do it would be:
inList = [1, 2, ... n]
outList = []
for i in inList:
for j in len(i):
if i%10 || i==0:
//there is a 0
outList.add(i)
break;
if(i<10)
//i cannot contain a 0
break;
i=i/10
Probibly only works with positive ints, but its trivial to account for negitive numbers.
Simple and efficient O(10N) or O(17N) according to your constraints
I am solving this problem -> http://www.spoj.com/problems/COINS/ . A very simple DP problem with a very straight forward DP approach.I found enough hints in the problem statement to use DP. All the test cases are running perfectly in my compiler but I am getting a WA in SPOJ. My code is as follows :
My code
#include <cstdio>
#include <map>
#include <cstring>
#include<algorithm>
using namespace std;
map< long long,long long > data;
map < long long,long long> :: iterator p;
int max(int a,int b)
{
if(a>b)return a;
return b;
}
long long calc(int n)
{
long long c;
if(n==0 || n==1 || n==2)
return n;
p = data.find(n);
if(p==data.end())
{
c = max(n, calc(n/2) + calc(n/3) + calc(n/4));
data.insert(p, pair < long long, long long > (n, c));
return c;
}
else return (*p).second;
}
int main()
{
int t;
long long n;
scanf("%d",&t);
if(t>10)return 0;
while(t--)
{
scanf("%lld",&n);
if(n<0 || n>1000000000)
break;
data.clear();
printf("%lld",calc(n));
}
return 0;
}
I am finding it really difficult for me to figure out where I am going wrong!
A test case which contradicts my code would also do.
Perhaps a stack overflow in calculate. The recursion is killing your program :-)
Or simply the fact that calculate(1000000000) is too much slow.
Use Dynamic programming , store your result in an array . Since the value can go upto 10^9, and you cann't take array of that size , just take array of size till 10^6 and store their result and rest value calculate using simple recursion .
Here is a solution in python
import sys
mydict = {}
def count(n):
if n <= 5:
return n
elif n in mydict.keys():
return mydict[n]
else:
k=max(n,count(n / 2) + count(n / 3) + count(n / 4))
mydict[n]=k
return mydict[n]
for line in sys.stdin:
res = count(int(line))
print(int(res))
Here's my solution, uses dp :
#include<bits/stdc++.h>
using namespace std;
map<long long int,long long int> m;
long long int dp(long long int k){
long long int a;
if(k==0){
return 0;
}
a=m[k];
/* if(k<12){
return k;
} */
if(k<12){
return k;
}
else if(a==0){
a=max(k,dp(k/2)+dp(k/4)+dp(k/3));
m[k]=a;
}
return a;
}
int main(){
long long int n,t;
while(scanf("%lld",&n)>0){
t=dp(n);
cout << t << endl;
}
return 0;
}