There are n groups of friends staying in the queue in front of bus station. The i-th group consists of ai men. Also, there is a single bus that works on the route. The size of the bus is x, that is it can transport x men simultaneously.
When the bus comes (it always comes empty) to the bus station, several groups from the head of the queue goes into the bus. Of course, groups of friends don't want to split, so they go to the bus only if the bus can hold the whole group. In the other hand, none wants to lose his position, that is the order of groups never changes.
The question is: how to choose the size x of the bus in such a way that the bus can transport all the groups and everytime when the bus moves off the bus station there is no empty space in the bus (the total number of men inside equals to x)?
Input Format:
The first line contains the only integer n (1≤n≤10^5). The second line contains n space-separated integers a1,a2,…,an (1≤ai≤10^4).
Output Format:
Print all the possible sizes of the bus in the increasing order.
Sample:
8
1 2 1 1 1 2 1 3
Output:
3 4 6 12
I made this code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(void)
{
int max=0,sum=0,i,n;
cin>>n;
int values[100000];
for ( i = 0; i < n; i++ )
{
cin>>values[i];
sum = sum + values[i];
if ( values[i] > max )
max = values[i];
}
int p = 0,j;
int count = 0;
vector<int> final;
for ( i = 0; i < n; i++ )
{
p = p + values[i];
j = 0;
if ( p >= max && sum%p == 0)
{
flag = 0;
while ( j < n )
{
garb = p;
while (garb!= 0)
{
garb = garb - values[j++];
if ( garb < 0 )
flag = 1;
}
}
if ( flag == 0 )
{
final.push_back(p);
count++;
}
}
}
sort(final.begin(),final.end());
for ( j = 0; j < count; j++ )
{
cout<<final[j]<<"\t";
}
return 0;
}
Edit: I did this in which basically, I am checking if the found divisor satisfies the condition, and if at any point of time, I get a negative integer on taking difference with the values, I mark it by using a flag. However, it seems to give me a seg fault now. Why?
I firstly, calculated the maximum value out of the all possible values, and then, I checked if its a divisor of the sum of the values. However, this approach doesn't work for the input as:
10
2 2 1 1 1 1 1 2 1 2
My output is
2 7 14
whereas the output should be
7 14
only.
Any other approach that I can go with?
Thanks!
I can think of the following simple solution (since your present concern is correctness and not time complexity):
Calculate the sum of all ai's (as you are already doing).
Calculate the maximum of all ai's (as you are already doing).
Find all the factors of sum that are > max(ai).
For each factor, iterate through the ai's and check whether the bus condition is satisfied.
Related
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 number is huge (cannot fit in the bounds of unsigned long long int in C++). How do we check?
There is a solution given here but it doesn't make much sense.
The solution here tries to repeatedly divide the large number (represented as a string) by 2 but I'm not sure I understand how the result is reached step by step.
Can someone please explain this or propose a better solution?
We cannot use any external libraries.
This is the sample code:
int isPowerOf2(char* str)
{
int len_str = strlen(str);
// sum stores the intermediate dividend while
// dividing.
int num = 0;
// if the input is "1" then return 0
// because 2^k = 1 where k >= 1 and here k = 0
if (len_str == 1 && str[len_str - 1] == '1')
return 0;
// Divide the number until it gets reduced to 1
// if we are successfully able to reduce the number
// to 1 it means input string is power of two if in
// between an odd number appears at the end it means
// string is not divisible by two hence not a power
// of 2.
while (len_str != 1 || str[len_str - 1] != '1') {
// if the last digit is odd then string is not
// divisible by 2 hence not a power of two
// return 0.
if ((str[len_str - 1] - '0') % 2 == 1)
return 0;
// divide the whole string by 2. i is used to
// track index in current number. j is used to
// track index for next iteration.
for (int i = 0, j = 0; i < len_str; i++) {
num = num * 10 + str[i] - '0';
// if num < 2 then we have to take another digit
// to the right of A[i] to make it bigger than
// A[i]. E. g. 214 / 2 --> 107
if (num < 2) {
// if it's not the first index. E.g 214
// then we have to include 0.
if (i != 0)
str[j++] = '0';
// for eg. "124" we will not write 064
// so if it is the first index just ignore
continue;
}
str[j++] = (int)(num / 2) + '0';
num = (num) - (num / 2) * 2;
}
str[j] = '\0';
// After every division by 2 the
// length of string is changed.
len_str = j;
}
// if the string reaches to 1 then the str is
// a power of 2.
return 1;
}
I'm trying to understand the process in the while loop. I know there are comments but they arent really helping me glean through the logic.
Let's start by figuring out how to halve a "string-number". We'll start with 128 as an example. You can halve each digit in turn (starting from the left), keeping in mind that an odd number affects the digit on the right(a). So, for the 1 in 128, you halve that to get zero but, because it was odd, five should be kept in storage to be added to the digit on its right (once halved):
128
v
028
Then halve the 2 as follows (adding back in that stored 5):
028
v
018
v
068
Because that wasn't odd, we don't store a 5 for the next digit so we halve the 8 as follows:
068
v
064
You can also make things easier then by stripping off any leading zeros. From that, you can see that it correctly halves 128 to get 64.
To see if a number is a power of two, you simply keep halving it until you reach exactly 1. But, if at any point you end up with an odd number (something ending with a digit from {1, 3, 5, 7, 9}, provided it's not the single-digit 1), it is not a power of two.
By way of example, the following Python 3 code illustrates the concept:
import re, sys
# Halve a numeric string. The addition of five is done by
# Choosing the digit from a specific set (lower or upper
# digits).
def half(s):
halfS = '' # Construct half value.
charSet = '01234' # Initially lower.
for digit in s: # Digits left to right.
if digit in '13579': # Select upper for next if odd.
nextCharSet = '56789'
else:
nextCharSet = '01234' # Otherwise lower set.
halfS += charSet[int(digit) // 2] # Append half value.
charSet = nextCharSet # And prep for next digit.
while halfS[0] == '0': # Remove leading zeros.
halfS = halfS[1:]
return halfS
# Checks for validity.
if len(sys.argv) != 2:
print('Needs a single argument')
sys.exit(1)
num = sys.argv[1]
if not re.match('[1-9][0-9]*', num):
print('Argument must be all digits')
sys.exit(1)
print(num)
while num != '1':
if num[-1:] in '13579':
print('Reached odd number, therefore cannot be power of two')
sys.exit(0)
num = half(num)
print(num)
print('Reached 1, was therefore power of two')
Running that with various (numeric) arguments will show you the process, such as with:
pax$ python ispower2.py 65534
65534
32767
Reached odd number, therefore cannot be power of two
pax$ python ispower2.py 65536
65536
32768
16384
8192
4096
2048
1024
512
256
128
64
32
16
8
4
2
1
Reached 1, was therefore power of two
(a) Take, for example, the number 34. Half of the 3 is 1.5 so the 1 can be used to affect that specific digit position but the "half" left over can simply be used by bumping up the digit on the right by five after halving it. So the 4 halves to a 2 then has five added to make 7. And half of 34 is indeed 17.
This solution does work only for numbers which are not too large i.e. fits in the range of unsigned long long int.
Simpler C++ solution using bitmanipulation for small numbers :-
int power(string s) {
// convert number to unsigned long long int
// datatype can be changed to long int, int as per the requirement
// we can also use inbuilt function like stol() or stoll() for this
unsigned long long int len = s.length();
unsigned long long int num = s[0]-'0';
for(unsigned long long int i = 1; i<len; i++)
num = (num*10)+(s[i]-'0');
if(num == 1)
return 0;
//The powers of 2 have only one set bit in their Binary representation
//If we subtract 1 from a power of 2 what we get is 1s till the last unset bit and if we apply Bitwise AND operator we should get only zeros
if((num & (num-1)) == 0)
return 1;
return 0;
}
A bit better solution that I could code in Java, which doesn't use any fancy object like BigInteger. This approach is same as simple way of performing division. Only look out for remainder after each division. Also trim out the leading zeroes from the quotient which becomes new dividend for next iteration.
class DivisionResult{
String quotient;
int remainder;
public DivisionResult(String q, int rem){
this.quotient = q;
this.remainder = rem;
}
}
public int power(String A) {
if (A.equals("0") || A.equals("1")) return 0;
while (!A.equals("1")){
DivisionResult dr = divideByTwo(A);
if (dr.remainder == 1) return 0;
A = dr.quotient;
}
return 1;
}
public DivisionResult divideByTwo(String num){
StringBuilder sb = new StringBuilder();
int carry = 0;
for (int i = 0;i < num.length(); i++){
int divisibleNum = carry*10 + (num.charAt(i) - '0');
carry = divisibleNum%2;
sb.append(divisibleNum/2);
}
return new DivisionResult(sb.toString().replaceAll("^0+(?!$)", ""), carry);
}
I am writing code in Hackerrank. And recently the problem said, convert decimal to base 2 and then count the max consecutive 1's in the binary number. And first I come with following solution. It works fine. But I do not understand the counting part of it, even though I wrote it.
The code is
int main(){
int n,ind=0, count=0, mmax=0;
char bin[100];
cin >> n;
while(n){
if(n%2==0) {
bin[ind]='0';
n = n / 2;
ind = ind + 1;
}
else if(n%2==1) {
bin[ind]='1';
n = n / 2;
ind = ind + 1;
}
}
for(int i=0; i<=(ind-1); i++){
if(bin[i] == '1' && bin[i+1] == '1'){
count++;
if(mmax < count)
mmax = count;
}
else
count=0;
}
cout << mmax + 1 << endl;
return 0;
}
In the above code, I guess that variable mmax will give me the max consecutive number of 1's but it gives me value that has (max consecutive - 1), So I just wrote like that and submitted the code. But I am curious about. why it is working that way. I am little bit of confused the way that code works like this.
Thanks
Lets say you have this binary sequence:
11110
Your code will compare starting from the first and second:
|11|110 1 && 1 -> max = 1
1|11|10 1 && 1 -> max = 2
11|11|0 1 && 1 -> max = 3
111|10| 1 && 0 -> max = 3
you can see, that although there are 4 1's you only do 3 comparisons, so your max will always be -1 of the actual max. You can fix this by adding mmax += 1 after your for loop.
Just a little bit of trace using small example will show why.
First, lets say there is only 1 '1' in your array.
Since you require both the current position and your next position to be '1', you will always get 0 for this case.
Let's say I have "11111". At the first '1', since next position is also '1', you increment count once. This repeats until 4th '1' and you increment your count 4 times in total so far. When you reach 5th '1', your next position is not '1', thus your count stops at 4.
In general, your method is like counting gaps between fingers, given 5 fingers, you get 4 gaps.
Side note: your code will fail for the case when there is no '1' in your array.
Here the question
At the Infinite House of Pancakes, there are only finitely many pancakes, but there are infinitely many diners who would be willing to eat them! When the restaurant opens for breakfast, among the infinitely many diners, exactly D have non-empty plates; the ith of these has Pi pancakes on his or her plate. Everyone else has an empty plate.
Normally, every minute, every diner with a non-empty plate will eat one pancake from his or her plate. However, some minutes may be special. In a special minute, the head server asks for the diners' attention, chooses a diner with a non-empty plate, and carefully lifts some number of pancakes off of that diner's plate and moves those pancakes onto one other diner's (empty or non-empty) plate. No diners eat during a special minute, because it would be rude.
You are the head server on duty this morning, and it is your job to decide which minutes, if any, will be special, and which pancakes will move where. That is, every minute, you can decide to either do nothing and let the diners eat, or declare a special minute and interrupt the diners to make a single movement of one or more pancakes, as described above.
Breakfast ends when there are no more pancakes left to eat. How quickly can you make that happen?
Input
The first line of the input gives the number of test cases, T. T test cases follow. Each consists of one line with D, the number of diners with non-empty plates, followed by another line with D space-separated integers representing the numbers of pancakes on those diners' plates.
Output
For each test case, output one line containing "Case #x: y", where x is the test case number (starting from 1) and y is the smallest number of minutes needed to finish the breakfast.
Limits
1 ≤ T ≤ 100.
Small dataset
1 ≤ D ≤ 6.
1 ≤ Pi ≤ 9.
Large dataset
1 ≤ D ≤ 1000.
1 ≤ Pi ≤ 1000.
Sample
Input
3
1
3
4
1 2 1 2
1
4
Output
Case #1: 3
Case #2: 2
Case #3: 3
and this is my source code
int result = 0, D = 0;
int part(vector<int> v1) {
if(v1[D - 1] == 0)
return 0;
int t1 = 0, t2 = 0, t3 = 0, i = 0;
vector<int> v2;
for(i = 0; i < D; ++i)
if(v1[i])
v2.push_back(v1[i] - 1);
else
v2.push_back(0);
if(v1[D - 1] == 1)
v1[D - 1] = 0;
else if( v1[D-1] % 2 )
v1[ D- 1 ] = ( v1[D-1] / 2 ) + 1;
else
v1[ D -1 ] = v1[ D - 1 ] / 2;
sort(v1.begin(),v1.end());
t1 = 1 + part(v1);
t2 = 1 + part(v2);
t3 = min(t1,t2);
return t3;
}
int main(void) {
int T = 0, count = 0;
scanf("%d",&T);
while(T--) {
vector<int> v1;
vector<int> ::iterator it;
int i = 0, temp = 0; D = 0;
result = 0;
++count;
scanf("%d",&D);
for(i = 0; i < D; ++i) {
scanf("%d",&temp);
v1.push_back(temp);
}
sort( v1.begin(), v1.end() );
result = part(v1);
printf("Case #%d: %d\n",count,result);
}
return 0;
}
I am basically trying to solve the coin change problem through recursion and here is what i have so far -:
#include<iostream>
#include<conio.h>
using namespace std;
int a[]={1,2,5,10,20,50,100,200},count=0;
//i is the array index we are working at
//a[] contains the list of the denominations
//count keeps track of the number of possibilities
void s(int i,int sum) //the function that i wrote
{
if (!( i>7 || sum<0 || (i==7 && sum!=0) )){
if (sum==0) ++count;
s(i+1,sum);
s(i,sum-a[i]);
}
}
int c(int sum,int i ){ //the function that I took from the algorithmist
if (sum == 0)
return 1;
if (sum < 0)
return 0;
if (i <= 0 && sum > 0 )
return 1;
return (c( sum - a[i], i ) + c( sum, i - 1 ));
}
int main()
{
int a;
cin>>a;
s(0,a);
cout<<c(a,7)<<endl<<count;
getch();
return 0;
}
The first function that is s(i,sum) has been written by me and the second function that is c(sum,i) has been taken from here - (www.algorithmist.com/index.php/Coin_Change).
The problem is that count always return a way higher value than expected. However, the algorithmist solution gives a correct answer but I cannot understand this base case
if (i <= 0 && sum > 0 ) return 1;
If the index (i) is lesser than or equal to zero and sum is still not zero shouldn't the function return zero instead of one?
Also I know that the algorithmist solution is correct because on Project Euler, this gave me the correct answer.
I guess that your problem is "Assuming that I have unlimited support of coins, on how many ways can I change the given sum"?
The algoritimists solution you gave assumes also, that the smallest denomination is 1. Otherwise it will won't work correctly.
Now your question:
if (i <= 0 && sum > 0 ) return 1;
Notice, that the only possibility that i<0 is that you called it with this value - no recursive call will be made with negative value of i. Such case (i<0) is an error so no result is proper (maybe assertion or exception would be better).
Now if i=0, assuming that at index 0 there is coin of value 1 means that there is only one way to exchange sum with this denomination - give sum coins of value 1. Right?
After a moment of thought I found out how to remove assumption that a[0] == 1. Change
if (i <= 0 && sum > 0 ) return 1;
into
if (i <= 0 && sum > 0 ) return sum % a[0] == 0 ? 1 : 0;
I believe the algorithm to be biased towards the choice of denominations, and assumes that there will be only one coin of the smallest denomination. Consider as a counter example of the correctness that there was no 2 coins, just 1,5,... And that the target to return was 4:
(4,1)
(-1,1) -> cut, sum<0 a[1]==5
(4,0) -> i==0 => 1
Either that or you misimplemented the algorithm (can there be an off by one error? Could it be i<0, or the original array be 1-based?)