Code Chef DSA Learning Series : Multiple of 3 Multhree - c++

My algorithm is different from question previously uploaded so please don't close it by seeing the same topic of the question
Consider a very long K-digit number N with digits d0, d1, ..., dK-1 (in decimal notation; d0 is the most significant and dK-1 the least significant digit). This number is so large that we can't give it to you on the input explicitly; instead, you are only given its starting digits and a way to construct the remainder of the number.
Specifically, you are given d0 and d1; for each i ≥ 2, di is the sum of all preceding (more significant) digits, modulo 10 — more formally, the following formula must hold:
Determine if N is a multiple of 3.
Input
The first line of the input contains a single integer T denoting the number of test cases. The description of T test cases follows.
The first and only line of each test case contains three space-separated integers K, d0 and d1.
Output
For each test case, print a single line containing the string "YES" (without quotes) if the number N is a multiple of 3 or "NO" (without quotes) otherwise.
Example
Input:
3
5 3 4
13 8 1
760399384224 5 1
Output:
NO
YES
YES
Explanation
Example case 1: The whole number N is 34748, which is not divisible by 3, so the answer is NO.
Example case 2: The whole number N is 8198624862486, which is divisible by 3, so the answer is YES.
question link
I am not able to understand whats wrong with this code,
it doesn't work with this test case:
input : 1 760399384224 5 1
#include <iostream>
using namespace std;
int main() {
// your code goes here
int t;
std::cin >> t;
for(int i=0;i<t;i++)
{
long long k,d0,d1,sum=0,x;
std::cin >> k>>d0>>d1;
sum=d0+d1;
for(;k>2;k--)
{
x=sum;
int z=x%10;
if(z==0)
break;
sum=sum+z;
}
cout<<sum<<endl;
/*if(sum>10)
{
long long a=sum/10;
long long b=sum%10;
sum=a+b;
}*/
if(sum%3==0)
sum=0;
if(sum%3==0)
{
std::cout << "YES" << std::endl;
}
else
std::cout << "NO" << std::endl;
}
return 0;
}

Related

Why does this C++ code give memory limit exceeded?

This is the question Im trying to solve: Link
Im running this code in an online editor and it gives a memory limit exceeded, even though I have used str+=c instead of str=str+c. And I cant seem to figure out why. Could anyone help me wth this?
#include <bits/stdc++.h>
using namespace std;
void solve(){
int a,b,x;
cin>>a>>b>>x;
string res="";
res+='0';
a--;
while(x--){
cout<<res;
res+=res.back()=='0'?'1':'0';
if(res.back()=='0')
a--;
else
b--;
}
string ans="";
for(char ch: res){
ans+=ch;
if(ch=='0'){
while (a--){
ans+='0';
}
}
else{
while(b--){
ans+='1';
}
}
}
cout<<ans;
}
int main() {
int t;
t=1;
while(t--){
solve();
}
return 0;
}
The input I give is 3 3 3
and output I expect is 101100
Basically your solution idea is nearly correct.
The most important requirement here is the number of tansitions. So, when we go from a 1 to a 0 or from a 0 to a 1. These transitions must exist. And the number of transisitions also determines the minimum numbers of 0es or 1s needed.
If more 0es or 1s should be present, then you can simply repeat any 0 or 1 with the same value. This will have no impact on the transistion.
Let's have a closer look. Below is an example for the minimum number of 0es or 1s for a given number of transitions
Transitions Sequence Min 0es Min 1s
1 01 1 1
2 010 2 1
3 0101 2 2
4 01010 3 2
5 010101 3 3
6 0101010 4 3
You immediately see that there is a simple mathematical relation between the number of transitions and the minimum number of needed 1s or 0es. It is:
(Number of Transitions + 1)/2 rounded up
(Number of Transitions + 1)/2 rounded down
For odd number of transisitions, the minimum numbers of 1s or 0es are always the same. For even numbers of transitions however, it depends on the starting value.
The reverse conclusion is that it does not matter for odd transitions, if you start with a 0 or a 1. For an even number of transitions it is important.
Example:
Input 1 2 2, meaning one 0, two 1s and 2 transitions.
With the above formula, we calculate that we need two digits of the one and 2 digits for the other, so theoretically 010 or 101, But since we shall use only one 0, it can only be 101
Resulting in: If we have an even number of transitions, then the start value may depend from other input parameters. And more precicely: If the minimum number needed for a digit is equal to the given number for that digit, then we must start with the other digit.
Example:
1 2 2 must be 101
2 2 2 can be 0110 or 1001
Knowing that we can now draft an algorithm. We will work only one one of the many solutions.
Check, if the number of transitions is odd or even
If even, then determine the start digit with above condition
create a sequence of 010101... or 10101... depending on the start digit and the given number of sequences
Add the not yet consumed 0es or 1s to the sequence by simply duplicating or repeating existing 0es or ones.
This can then be implemented in a similar way like your approach:
#include <iostream>
#include <string>
int main() {
// Here we will store the input parameters
int numberOfZeroes{}, numberOfOnes{}, numberOfTransitions{};
// The input will always be correct, so need to check it
std::cin >> numberOfZeroes >> numberOfOnes >> numberOfTransitions;
// Start digit
char digit{ '0' };
// Check, if the number of transitions is even, then we need a special additional check
if (numberOfTransitions % 2 == 0) {
// Calculate the minimum number of needed 0es or 1s
const int minimum = (numberOfTransitions + 1) / 2;
// Check, if we need to start with digit 1
if (minimum == numberOfZeroes)
digit = '1';
}
// Now we want to create a string starting made of alternating 0es and 1s, so transitions
std::string sequenceWithTransitions{};
do {
// Build string
sequenceWithTransitions += digit;
// Update counters and digits
if (digit == '1') {
digit = '0'; // Make transition
--numberOfOnes; // Update counter
}
else {
digit = '1'; // Make transition
--numberOfZeroes; // Update counter
}
} while (numberOfTransitions--);
// Fill in the remaining 0es and 1s
std::string result{};
for (char c : sequenceWithTransitions) {
result += c; // Copy value
if (c == '1') // Potential replications of 1
while (numberOfOnes-- > 0)
result += '1';
if (c == '0') // Potential replications of 0
while (numberOfZeroes-- > 0)
result += '0';
}
std::cout << result << '\n';
}
Of course this code can be optimzied in many ways

How to make my CodeChef solution code faster?

I am a beginner currently in first semester. I have been practising on Code Chef and am stuck at this problem. They are asking to reduce the execution time of my code. The problem goes as follows:
Meliodas and Ban are fighting over chocolates. Meliodas has X chocolates, while Ban has Y. Whoever has lesser number of chocolates eats as many chocolates as he has from the other's collection. This eatfest war continues till either they have the same number of chocolates, or at least one of them is left with no chocolates.
Can you help Elizabeth predict the total no of chocolates they'll be left with at the end of their war?
Input:
First line will contain T, number of testcases. Then the testcases follow.
Each testcase contains of a single line of input, which contains two integers X,Y, the no of chocolates Meliodas and Ban have, respectively.
Output:
For each testcase, output in a single line the no of chocolates that remain after Ban and Meliodas stop fighting.
Sample Input:
3
5 3
10 10
4 8
Sample Output:
2
20
8
My code is as follows:
#include <iostream>
using namespace std;
int main()
{
unsigned int t,B,M;
cin>>t;
while(t--)
{
cin>>M>>B;
if(B==M)
{
cout<<B+M<<endl;
}
else
{
for(int i=1;B!=M;i++)
{
if(B>M)
B=B-M;
else
M=M-B;
}
cout<<M+B<<endl;
}
}
return 0;
}
Assuming that Band Mare different from 0, this algorithm corresponds to one version of the Euclidean algorithm. Therefore, you can simply:
std::cout << 2 * std::gcd(B, M) << "\n";
If at least one of the quantity is equal to 0, then just print B + M.
After realizing that your code was correct, I wondered where could be any algorithmic improvement. And I realized that eating as many chocolate from the peer as one has was in fact close to a modulo operation. If both number are close, a minus operation could be slightly faster than a modulo one, but if one number is high, while the other is 1, you immediately get it instead of looping a great number of times...
The key to prevent stupid errors is to realize that if a modulo is 0, that means that the high number is a multiple of the small one and we must stop immediately writing twice the lower value.
And care should be taken that if one of the initial counts are 0, the total number will never change.
So the outer loop should become:
if(B==M || B == 0 || M == 0)
{
cout<<B+M<<"\0";
}
else {
for (;;) {
if (M < B) {
B = B % M;
if (B == 0) {
cout << M * 2 << '\n';
break;
}
}
else {
M = M % B;
if (M == 0) {
cout << B * 2 << '\n';
break;
}
}
}
}
...
Note: no infinite loop is possible here because a modulo ensures that for example is M > B > 0' after M = M % Byou will haveB > M >= 0and as the case== 0` is explicitely handled the number of loops cannot be higher than the lower number.

My code is failing a test due to time limit restriction, how do I decrease the time taken by my code to work?

Question - You are given two positive integers a and b. In one move you can increase a by 1 (replace a with a+1). Your task is to find the minimum number of moves you need to do in order to make a divisible by b. It is possible, that you have to make 0 moves, as a is already divisible by b. You have to answer t independent test cases.
Input -
The first line of the input contains one integer t (1≤t≤10^4) — the number of test cases. Then t test cases follow.
The only line of the test case contains two integers a and b (1≤a,b≤10^9).
Output -
For each test case print the answer — the minimum number of moves you need to do in order to make a divisible by b.
Code Forces question link - https://codeforces.com/problemset/problem/1328/A
Time Limit - 1 second per test case
My code -
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
long long t,a,b,x;
cin >> t;
for(long long i=0;i<t;i++){
cin >> a >> b;
x = a;
while(a%b!=0){
a++;
}
cout << a-x << endl;
}
}
It is failing when the number of test cases is 10000 and there are big input numbers. What can I do to decrease the execution time of my code?
You need to find m such that a + m = kb with 0≤m<b (you want the next multiple). If we divide the equation by b, we have (a + m)/b = k, which is also k = ceiling(a/b).
So m = ceiling(a/b) b - a.

Cross sum calculation, Can anyone explain the code please?

i'm going to learn C++ at the very beginning and struggling with some challenges from university.
The task was to calculate the cross sum and to use modulo and divided operators only.
I have the solution below, but do not understand the mechanism..
Maybe anyone could provide some advice, or help to understand, whats going on.
I tried to figure out how the modulo operator works, and go through the code step by step, but still dont understand why theres need of the while statement.
#include <iostream>
using namespace std;
int main()
{
int input;
int crossSum = 0;
cout << "Number please: " << endl;
cin >> input;
while (input != 0)
{
crossSum = crossSum + input % 10;
input = input / 10;
}
cout << crossSum << endl;
system ("pause");
return 0;
}
Lets say my input number is 27. cross sum is 9
frist step: crossSum = crossSum + (input'27' % 10 ) // 0 + (modulo10 of 27 = 7) = 7
next step: input = input '27' / 10 // (27 / 10) = 2.7; Integer=2 ?
how to bring them together, and what does the while loop do? Thanks for help.
Just in case you're not sure:
The modulo operator, or %, divides the number to its left by the number to its right (its operands), and gives the remainder. As an example, 49 % 5 = 4.
Anyway,
The while loop takes a conditional statement, and will do the code in the following brackets over and over until that statement becomes false. In your code, while the input is not equal to zero, do some stuff.
To bring all of this together, every loop, you modulo your input by 10 - this will always return the last digit of a given Base-10 number. You add this onto a running sum (crossSum), and then divide the number by 10, basically moving the digits over by one space. The while loop makes sure that you do this until the number is done - for example, if the input is 104323959134, it has to loop 12 times until it's got all of the digits.
It seems that you are adding the digits present in the input number. Let's go through it with the help of an example, let input = 154.
Iteration1
crossSum= 0 + 154%10 = 4
Input = 154/10= 15
Iteration2
crossSum = 4 + 15%10 = 9
Input = 15/10 = 1
Iteration3
crossSum = 9 + 1%10 = 10
Input = 1/10 = 0
Now the while loop will not be executed since input = 0. Keep a habit of dry running through your code.
#include <iostream>
using namespace std;
int main()
{
int input;
int crossSum = 0;
cout << "Number please: " << endl;
cin >> input;
while (input != 0) // while your input is not 0
{
// means that when you have 123 and want to have the crosssum
// you first add 3 then 2 then 1
// mod 10 just gives you the most right digit
// example: 123 % 10 => 3
// 541 % 10 => 1 etc.
// crosssum means: crosssum(123) = 1 + 2 + 3
// so you need a mechanism to extract each digit
crossSum = crossSum + input % 10; // you add the LAST digit to your crosssum
// to make the number smaller (or move all digits one to the right)
// you divide it by 10 at some point the number will be 0 and the iteration
// will stop then.
input = input / 10;
}
cout << crossSum << endl;
system ("pause");
return 0;
}
but still dont understand why theres need of the while statement
Actually, there isn't need (in literal sense) for, number of digits being representable is limited.
Lets consider signed char instead of int: maximum number gets 127 then (8-bit char provided). So you could do:
crossSum = number % 10 + number / 10 % 10 + number / 100;
Same for int, but as that number is larger, you'd need 10 summands (32-bit int provided)... And: You'd always calculate the 10 summands, even for number 1, where actually all nine upper summands are equal to 0 anyway.
The while loop simplifies the matter: As long as there are yet digits left, the number is unequal to 0, so you continue, and as soon as no digits are left (number == 0), you stop iteration:
123 -> 12 -> 1 -> 0 // iteration stops, even if data type is able
^ ^ ^ // to store more digits
Marked digits form the summands for the cross sum.
Be aware that integer division always drops the decimal places, wheras modulo operation delivers the remainder, just as in your very first math lessons in school:
7 / 3 = 2, remainder 1
So % 10 will give you exactly the last (base 10) digit (the least significant one), and / 10 will drop this digit afterwards, to go on with next digit in next iteration.
You even could calculate the cross sum according to different bases (e. g. 16; base 2 would give you the number of 1-bits in binary representation).
Loop is used when we want to repeat some statements until a condition is true.
In your program, the following statements are repeated till the input becomes 0.
Retrieve the last digit of the input. (int digit = input % 10;)
Add the above retrieved digit to crosssum. (crosssum = crosssum + digit;)
Remove the last digit from the input. (input = input / 10;)
The above statements are repeated till the input becomes zero by repeatedly dividing it by 10. And all the digits in input are added to crosssum.
Hence, the variable crosssum is the sum of the digits of the variable input.

SPOJ LASTDIG, getting TLE

Below is my code for the problem. I am getting TLE. Can anyone tell me how to fix it.
Here is the problem statement:
Nestor was doing the work of his math class about three days but he is tired of make operations a lot and he should deliver his task tomorrow. His math’s teacher gives two numbers a and b. The problem consist in find the last digit of the potency of base a and index b. Help Nestor with his problem. You are given two integer numbers: the base a (0 <= a <= 20) and the index b (0 <= b <= 2,147,483,000), a and b both are not 0. You have to find the last digit of a^b.
Input
The first line of input contains an integer t, the number of test cases (t <= 30). t test cases follow. For each test case will appear a and b separated by space.
Output
For each test case output an integer per line representing the result.
Example
Input:
2
3 10
6 2
Output:
9
6
Here is my code
#include <iostream>
using namespace std;
int main() {
int t;
scanf("%d",&t);
int num;
unsigned int pow;
while(t--)
{
scanf("%d",&num);
scanf("%d",&pow);
int z=1;
if(num==0&&pow==0)
printf("1");
else
{
while(pow!=0)
{
z=z*num;
z=z%10;
pow--;
}
printf("%d\n",z);
}
}
return 0;
}
The value for b is too high, a simple approach such as yours is bound to give a TLE. You can solve this problem using Modular Exponentiation.
http://en.wikipedia.org/wiki/Modular_exponentiation