i have written a c++ code for generating first and last k digits of a number as large as 10^9. (k<=9).
cin>>n>>k;
cout << (unsigned long)floor(pow(10.0, modf(n*log10((double)n), &dummy) + k - 1)) << " "; // code that prints the first k digits
long long int ans = foo(n,k); // function that prints the last k digits
if(ans==0)
{
for(int i=0;i<k;i++) cout << "0";
}
else{
stringstream ss;
string s;
ss<<ans;
ss>>s;
if(s.size()!=k)
{
for(int i=0;i<(k-s.size());i++)
s="0"+s;
}
cout<<s;
}
where function foo() is:
long long int foo(int n, int k) // code of the function
{
long long int m=1;
for(; k > 0; k--) m*=10;
long long int r=1, t=n % m;
while(n)
{
if (n % 2)
r = r * t % m;
t = t * t % m;
n >>= 1;
}
return r;
}
this gives me output as:
if given 9 and 3 as inputs, it gives first and last 3 digits of 9 to the power 9 (9^9) i.e. 387 and 489. But I m still missing out some test cases.
Can anyone please help me finding out the test case for which my code wouldn't work ?
1 ≤ n ≤ 109, 1 ≤ k ≤ 9
the problem statement: http://www.codechef.com/problems/MARCHA4/
If n^n <= 10^9, in which case your code seems to work fine. However, if you allow bigger n, say 11^11, and ask for the last 4 digits of that, which are 0611, your code will only print 611. Basically, it doesn't print any leading zeroes when it should.
This doesn't really answer the question, and its almost trivially easy, but I figure it might be worth sharing. If there were a "long comment" capability I'd be using it.
EDIT: just noticed using str instead of repr will eliminate the L on its own
def firstAndLastDig(k, num):
s = str(num)
return (s[:k], s[-k:])
def firstAndLastDigSelfExp(k,n):
return firstAndLastDig(k,n**n)
Overflow is not an issue (the only thing is dealing with the L if you use repr instead of str),
firstAndLastDigSelfExp(6,12)
('891610', '448256')
firstAndLastDigSelfExp(42,491)
('209417336844579728122309696211520194012462', '160453713040914743773217804810667483135091')
And neither are leading zeroes
>>> firstAndLastDigSelfExp(4,9)
('3874', '0489')
This isn't do say the modular logs and stuff aren't cool - on the contrary I really liked reading about how you did this without generating the entire number. I didn't know about modf at all until reading OP's question and the body of foo is very interesting.
I think the problem is using floating point. Finding the first digit of a number actually requires perfect precision.
Unfortunately, the contest judge evidently doesn't understand that "number of significant digits" != "number of correct digits".
Perhaps there is some clever way to exactly compute (n*n, n = 10*9) without exhausting memory, but finding the first digits of a very good estimate is simply not the same as finding the first digits of the answer.
Assume that k = 9. Now, m = 1e9, and t <= 1e9 - 1.
t * t then may be as high as 1e18 - 2e9 + 1, which needs ... 59.8 bits.
Ok, not a problem with a 64-bit long long int, which has 63 bits of magnitude (and 1 of sign), but I'll leave this here so others don't repeat the same analysis.
Are you told that n is a positive integer? For example, (-8)^(-8) is perfectly well expressible in decimal but your program can't handle it.
Related
I am currently practicing algorithms and DS. I have stumbled upon a question that I can't figure out how to solve. So the question's link is there:
In summary, it says that there is a number of chairs in a circle, and the position of the person (relative to a certain chair), and how many M movements he should make.
So the input is as following:
3 integer numbers N, M, X , The number of chairs, the number of times the boy should move and the first chair he will start from respectively ( 1 ≤ X ≤ N < 2^63 , 0 ≤ M < 2^63 )
So, what have I done so far? I thought about the following:
So I thought that the relative position after M movements is (x+m) % n, and since this can cause Integer overflow, I have done it like that, ((x%n) + (m%n)) % n. I have figured out that if the person has reached the last index of chair, it will be 0 so I handled that. However, it passes only 2 tests. I don't need any code to be written, I want to directed in the right way of thinking. Here is my code so far:
#include <iostream>
using namespace std;
int main() {
long long n, m, x;
cin >> n >> m >> x;
// After each move, he reaches (X+1).
// X, N chairs.
// ((X % N) + (M % N)) % N;
// Odd conideration.
if ( m % 2 == 1) {
m += 1;
}
long long position = (x % n + m % n) % n;
if (position == 0) {
position = n;
}
cout << position;
return 0;
}
If the question required specific error handling, it should have stated so (so don't feel bad).
In every real-world project, there should be a standard to dictate what to do with weird input. Do you throw? Do you output a warning? If so, does it have to be translated to the system language?
In the absence of such instructions I would err toward excluding these values after reading them. Print an error to std::cerr (or throw an exception). Do this as close to where you read them as possible.
For overflow detection, you can use the methods described here. Some may disagree, and for a lab-exercise, it's probably not important. However, there is a saying in computing "Garbage in == Garbage out". It's a good habit to check for garbage before processing, rather than attempting to "recycle" garbage as you process.
Here's the problem:
Say the value of N is 2^63-1, and X and M are both 2^63 - 2.
When your program runs untill the ((X % N) + (M % N)) % N part,
X % N evaluates into 2^63 - 2 (not changed), and so does M % N.
Then, the addition between the two results occurs, 2^63 - 2 + 2^63 - 2 there is the overflow happening.
After the comment of #WBuck, the answer is actually rather easy which is to change the long long to unsigned because there are no negative numbers and therefore, increase the MAX VALUE of long long (when using unsigned).
Thank you so much.
Writing a program to solve problem four of project euler: Find the largest palindrome made from the product of two 2-digit numbers. Heres my reprex:
#include <iostream>
int reverseNumber(int testNum)
{
int reversedNum, remainder = 0;
int temp = testNum;
while(temp != 0)
{
remainder = temp % 10;
reversedNum = reversedNum * 10 + remainder;
temp /= 10;
}
return reversedNum;
}
int main()
{
const int MIN = 100;
int numOne = 99;
int product = 0;
for(int numTwo = 10; numTwo < 100; numTwo++)
{
product = numOne * numTwo;
if (reverseNumber(product) == product)
{
int solution = product;
std::cout << solution << '\n';
return 0;
}
}
return 0;
}
My main thought process behind this is that the for loop will go through every number from 10 to 99 and multiply it by 99. My intended outcome is for it to print 9009 which is the largest palindrome with 2 factors of 2 digits. So what I think should happen here is the for loop will go from 10 to 99, and each loop it should go through the parameters of the if statement which reverses the number and sees if it equals itself.
I've made sure it wasn't a compiler issue, as this is recurring between different compilers. The reverseNumber() function returns the proper number every time I've tested it, so that shouldn't be the problem, however this problem only occurs when the function is involved in the logical comparison. By this I mean if that even I set it equal to a variable and put the variable in the if parameters, the issue still occurs. I'm pretty much stumped. I just hope it's not some silly mistake as I've been on this for a couple days now.
int reversedNum, remainder = 0;
You should be aware that this gives you (in an automatic variable context) a zero remainder but an arbitrary reversedNum. This is actually one of the reasons some development shops have the "one variable per declaration" rule.
In other words, it should probably be:
int reversedNum = 0, remainder;
or even:
int reversedNum = 0;
int remainder;
One other thing that often helps out is to limit the scope of variable to as small an area as possible, only bringing them into existence when needed. An example of that would be:
int reverseNumber(int testNum) {
int reversedNum = 0;
while (testNum != 0) {
int remainder = testNum % 10;
reversedNum = reversedNum * 10 + remainder;
testNum /= 10;
}
return reversedNum;
}
In fact, I'd probably go further and eliminate remainder altogether since you only use it once:
reversedNum = reversedNum * 10 + testNum % 10;
You'll notice I've gotten rid of temp there as well. There's little to gain by putting testNum into a temporary variable since it's already a copy of the original (as it was passed in by value).
And one other note, more to do with the problem rather than the code. You seem to be assuming that there is a palindrome formed that is a multiple of 99. That may be the case but a cautious programmer wouldn't rely on it - if you're allowed to assume things like that, you could just replace your entire program with:
print 9009
Hence you should probably check all possibilities.
You also get the first one you find which is not necessarily the highest one (for example, let's assume that 99 * 17 and 99 * 29 are both palindromic - you don't want the first one.
And, since you're checking all possibilities, you probably don't want to stop at the first one, even if the nested loops are decrementing instead of incrementing. That's because, if 99 * 3 and 97 * 97 are both palindromic, you want the highest, not the first.
So a better approach may be to start high and do an exhaustive search, while also ensuring you ignore the palindrome check of candidates that are smaller that your current maximum, something like (pseudo-code)
# Current highest palindrome.
high = -1
# Check in reverse order, to quickly get a relatively high one.
for num1 in 99 .. 0 inclusive:
# Only need to check num2 values <= num1: if there was a
# better palindrome at (num2 * num1), we would have
# already found in with (num1 * num2).
for num2 in num1 .. 0 inclusive:
mult = num1 * num2
# Don't waste time doing palindrome check if it's
# not greater than current maximum - we can't use
# it then anyway. Also, if we find one, it's the
# highest possible for THIS num1 value (since num2
# is decreasing), so we can exit the num2 loop
# right away.
if mult > high:
if mult == reversed(mult):
high = mult
break
if high >= 0:
print "Solution is ", high
else:
print "No solution"
In addition to properly initializing your variables, if you want the largest palindrome, you should switch the direction of your for loop -- like:
for(int numTwo = 100; numTwo > 10; numTwo--) {
...
}
or else you are just printing the first palindrome within your specified range
input : integer ( i'll call it N ) and (1 <= N <= 5,000,000 )
output : integer, multiple of N and only contains 0,7
Ex.
Q1 input : 1 -> output : 7 ( 7 mod 1 == 0 )
Q2 input : 2 -> output : 70 ( 70 mod 2 == 0 )
#include <string>
#include <iostream>
using namespace std;
typedef long long ll;
int remaind(string num, ll m)
{
ll mod = 0;
for (int i = 0; i < num.size(); i++) {
int digit = num[i] - '0';
mod = mod * 10 + digit;
mod = mod % m;
}
return mod;
}
int main()
{
int n;
string ans;
cin >> n;
ans.append(n, '7');
for (int i = ans.length() - 1; i >= 0; i--)
{
if (remaind(ans, n) == 0)
{
cout << ans;
return 0;
}
ans.at(i) = '0';
}
return 0;
}
is there a way to lessen the time complexity?
i just tried very hard and it takes little bit more time to run while n is more than 1000000
ps. changed code
ps2. changed code again because of wrong code
ps3. optimize code again
ps4. rewrite post
Your approach is wrong, let's say you divide "70" by 5. Then you result will be 2 which is not right (just analyze your code to see why that happens).
You can really base your search upon numbers like 77777770000000, but think more about that - which numbers you need to add zeros and which numbers you do not.
Next, do not use strings! Think of reminder for a * b if you know reminder of a and reminder of b. When you program it, be careful with integer size, use 64 bit integers.
Now, what about a + b?
Finally, find reminders for numbers 10, 100, 1000, 10000, etc (once again, do not use strings and still try to find reminder for any power of 10).
Well, if you do all that, you'll be able to easily solve the whole problem.
May I recommend any of the boost::bignum integer classes?
I suspect uint1024_t (or whatever... they also have 128, 256, and 512, bit ints already typedefed, and you can declare your own easily enough) will meet your needs, allowing you to perform a single %, rather than one per iteration. This may outweigh the performance lost when using bignum vs c++'s built-in ints.
2^1024 ~= 1.8e+308. Enough to represent any 308 digit number. That's probably excessive.
2^512 ~= 1.34e+154. Good for any 154 digit number.
etc.
I suspect you should first write a loop that went through n = 4e+6 -> 5e+6 and wrote out which string got the longest, then size your uint*_t appropriately. If that longest string length is more than 308 characters, you could just whip up your own:
typedef number<cpp_int_backend<LENGTH, LENGTH, unsigned_magnitude, unchecked, void> > myReallyUnsignedBigInt;
The modulo operator is probably the most expensive operation in that inner loop. Performing once per iteration on the outer loop rather than at the inner loop (O(n) vs O(n^2)) should save you quite a bit of time.
Will that plus the whole "not going to and from strings" thing pay for bignum's overhead? You'll have to try it and see.
The statement check is where I don't understand why it shows wrong answer on submission when I write "sum = (solution[R]-solution[L-1])%mod;" instead. Here I have not added mod within the bracket. I don't see how the answer changes by adding a value of taking the mod of same. Problem code in codechef: https://www.codechef.com/problems/FFC219B
#include<iostream>
#define ll long long
#define mod 1000000007 //the modulus we need to take for the final answer
#define endl "\n"
using namespace std;
long long solution[100007] = {0}; //Initialising all the values with zero
int main(){
ios_base :: sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solution[0] = 0;
ll a1=1,a2=2,a3=3,a4=4; //The variable initialising as per the problem
for(int i = 1;i <= 100007;i++){
ll k=(a1 * a2) % mod * a3 % mod * a4 % mod;
solution[i] = (solution[i-1]+k)%mod; //Adding the previous values as we are to find the sum in range
a1++;
a2++;
a3++;
a4++;
}
int t; //Taking input for number of test cases
cin>>t;
while(t-->0)
{
int L,R;
cin>>L>>R; //Taking the range input
long long sum = 0;
sum = (solution[R]-solution[L-1] + mod)%mod; //statement check & final answer
cout<<sum<<endl;
}
return 0;
}
The program can give the incorrect answer since the correct answer must always be a positive - not a negative - number.
When you subtract consecutive modulo values, the result may well be negative even though the numbers themselves are increasing (eg, (4^3)%10 - (4^2)%10 = 64%10 - 16%10 = 4-6 = -2), . This means “solution[R]-solution[L-1]” may also well be negative, which means “(solution[R]-solution[L-1]) % mod” will also be negative - although clearly the answer (the number of people affected) must always be positive.
So adding the mod value in this fashion ensures that the result will always be positive.
Simply enough, I practice programming via an online judge. This is a rather stupid problem, really easy. However, The judge keeps saying I have a wrong answer. I'm just going to paste the code which is just a few lines, and a link to the problem.
#include <iostream>
#include <string>
using namespace std;
int main() {
int cases = 0;
string solution = "";
cin >> cases;
if (cases > 100)
return(0);
for (int i = 0; i < cases; i++) {
int temp = 0;
cin >> temp;
if ((temp % 4) == 0)
solution +="Y";
else
solution +="N";
}
for (int j = 0; j < cases; j++) {
if (solution[j] == 'Y')
cout << "YES";
else
cout << "NO";
cout << endl;
}
}
The problem is simply to output YES or NO for each number that is input that is divisible by 4, YES for if it is, NO if its not. The problem and every minute detail can be found: http://coj.uci.cu/24h/problem.xhtml?abb=1306
This is rather silly, but I'm going bonkers here trying to figure out what I'm doing WRONG!
A number is divisible by 4 if its two last decimal digits are divisible by 4.
The end.
P.S. Sometimes it makes sense to stop thinking as a programmer and remember algebra/arithmetics.
As I said in a comment, the problem is that you cannot read a 100 digit number into an int directly. I don't want to give you the solution to the algorithm, but a hint that should help: How many digits would you need to know if the number was divisible by 2 or by 5? And how could you extend that to 4?
If you express a number X as Y + d where d = X%100 and Y = X -d we can see that Y will always be divisible by 100, for example for the number X = 343535, Y would be 343500 and d would be 35. Since Y is divisible by 100, implies that is divisible by 4, so you can determinate if X is divisible by 4, checking if d is divisible by 4, i.e the last two digits of X.
Formally it would be:
Y = 4*Z
Y = 100*X +d
Y = 4*Z = 4*25*X +d
d = 4*(Z - 25*X)
i.e if Y is multiple of 4, d is multiple of 4
You have to apply this principle to solve your problem.
Simply read a raw string and check if the number represented by the last two characters are divisible by four.
As tempting as might be, you don't need a BitInteger to figure out whether a 100 digit number, of 1 million digit number is divisible by 4. That's just simple math, that you should be able to figure by yourself in a minute, if you don't know the rule.
Perhaps the problem is this if (cases > 100). because of this -1 would be a valid option.
Change to if (cases > 100 && cases < 1) to fix it
I wouldn't even read the whole number. I would just read the last 2 digits before the EOF char (end of file).
string inputString;
while(getline(cin,inputString)
{
//code for finding x %4==0 and output
}
then all you need to do is convert the last 2 chars into a int and then do your mod 4 code. (you'll need a catch value for numbers < 10, but that shouldn't be hard)