//A code to find Total of Electric Bill...
/*
Upto 100 Units - Rs 5 pu
upto 200 units - Rs 5.5 pu
upto 500 units - Rs 6.5 pu
above 500 units - Rs 7 pu
*/
#include<stdio.h>
int
main ()
{
int a;
float b=0.0;
printf ("Enter Your Consumption in Units: ");
scanf ("%d", &a);
if (a > 0)
b=b+(a*5);
if (a > 100)
b=b+((a-100)*5.5);
if (a > 200)
b=b+((a - 200) * 6.5);
if (a>500)
b=b+((a - 500) * 7);
printf("\n Your Bill is Rs. %f",b);
return 0;
}
On giving 750 as Input, the expected answer is 4750, but it is showing 12650.
also What would be a smarter method of doing this rather than using and and operators within each if statement?
With a equal 750 all if-statements will be true so your code will calculate 750 x 5 + (750-100) x 5.5 + (750-200) x 6.5 + (750-500) x 7 which is not what you want.
You could change the order of the if-statements and reduce a with the amount paid so far.
To keep it in the spirit of your code, it could look like:
if (a>500)
{
b=b+((a - 500) * 7);
a = 500;
}
if (a > 200)
{
b=b+((a - 200) * 6.5);
a = 200;
}
if (a > 100)
{
b=b+((a-100)*5.5);
a = 100;
}
b=b+(a*5);
A more "generic" and easier to maintain approach could be:
struct price_range
{
unsigned limit;
double price;
};
const struct price_range pr[] =
{
{ 0, 5.0},
{100, 5.5},
{200, 6.5},
{500, 7.0}
};
double calculate_price(unsigned amount)
{
size_t i = sizeof pr / sizeof pr[0];
double p = 0;
do
{
--i;
if (amount > pr[i].limit)
{
p += (amount - pr[i].limit) * pr[i].price;
amount = pr[i].limit;
}
} while (i > 0);
return p;
}
Related
I am trying to add two times like 20:30 + 1:40 = 22h 10m.
I'm having a problem with the remainder after the dot
#include <stdio.h>
float walking (float start,float duration);
int main() {
printf ("finish = %.2f", walking(20.30, 1.40));
return 0;
}
float walking(float start, float duration) {
int finMinuites = (int)(start * 100) % 100 + (int)(duration * 100) % 100;
int finHours = (start * 100) / 100 + (duration * 100) / 100;
if (finMinuites >= 60) {
finMinuites -= 60;
finHours++;
}
if (finHours >= 24)
finHours -= 24;
return finHours + finMinuites / 100;
}
If you really want to store time in a float then here is a solution:
#include<stdio.h>
#include<math.h>
float walking(float start,float duration);
int main() {
printf("finish = %.2f",walking(20.30, 1.40));
return 0;
}
int toMinutes(float time){
int t = (int)round((time*100));
int hours = t/100;
int min = t - hours * 100;
return hours*60+min;
}
float toFloat(int minutes){
int hours = minutes/60;
int min = minutes - hours * 60;
float t = hours * 100;
t += min;
t /= 100;
return t;
}
float walking(float start,float duration){
int mins = toMinutes(start) + toMinutes(duration);
int day = 24*60;
while(mins > day){
mins -= day;
}
return toFloat(mins);
}
But I would suggest storing the minutes as an int instead.
The difficult part is to break a floating point variable (FP) properly.
float/double cannot represent many values like 0.01 exactly and so
(int)(start * 100) fails edge cases when the minutes * 100 are a fraction just less than a whole number as (int) truncates.
Instead break the FP value into whole and fraction parts (modf()) to get the hours and minutes and then form a total single unit time value. Add. Then convert the sum back to hours.minutes.
Makes more sense to use double than float given OP is using double test case constants. Also float should be reserved for compelling conditions that require/benefit from them instead of the default double.
No need to scale to minutes. Makes for simpler code. Easy-peasy.
#include <math.h>
double to_hours(double hours_dot_minutes) {
double h;
double m = modf(hours_dot_minutes, &h) * 100.0;
return h + m/60.0;
}
double reduce_to_a_day(double hours) {
const double hours_per_day = 24.0;
hours = fmod(hours, hours_per_day);
if (hours < 0.0) {
hours += hours_per_day;
}
return hours;
}
double to_hours_dot_minutes(double hours) {
double h;
double m = modf(hours, &h) * 60.0;
return h + m/100.0;
}
double walking(double start, double duration) {
double sum = to_hours(start) + to_hours(duration);
sum = reduce_to_a_day(sum);
return to_hours_dot_minutes(sum);
}
Notice that int math is not used anywhere. IMO, floating point problems best handled with FP math, integer problems with integer math and text problems with text manipulation. Mixing approaches often encounters issues in edge cases - as in OP's use of (int) for a FP problem.
If still wanting to use a cast over a limited range of values,
double walking(double start, double duration) {
int start_h = (int) start;
int duration_h = (int) duration;
double sum = start_h + duration_h +
((start - start_h) + (duration - duration_h)) * 100.0 / 60.0;
while (sum >= 24.0) sum -= 24.0;
int sum_h = (int) sum;
return sum_h + (sum - sum_h) * 60.0 / 100.0;
}
As suggested by #ryyker, you can make life simple with strings without changing the calling parameters:
#include <stdio.h>
#include <stdlib.h>
double walking( double bgn, double dur ) {
printf( "Start = %5.2f duration = %5.2f ", bgn, dur );
char str[32];
sprintf( str, "%.2f %.2f", bgn, dur );
int res = 0, cnt = 1;
for( char *cp = str; ( cp = strtok( cp, " ." ) ) != NULL; cp = NULL )
res += atoi( cp ) * (cnt&1 ? 60 : 1), cnt++;
return res/60%24 + ((res%60)*0.01);
}
int main() {
double pairs[][2] = {
{ 20.30, 1.40 },
{ 1.47, 1.13 },
{ 0.00, 1.13 },
{ 0.00, 0.00 },
{ 23.59, 0.01 },
{ 12.00, 48.27 },
};
for( int i = 0; i < sizeof pairs/sizeof pairs[0]; i++ )
printf ( "finish = %5.2f\n", walking( pairs[i][0], pairs[i][1] ) );
return 0;
}
Output
Start = 20.30 duration = 1.40 finish = 22.10
Start = 1.47 duration = 1.13 finish = 3.00
Start = 0.00 duration = 1.13 finish = 1.13
Start = 0.00 duration = 0.00 finish = 0.00
Start = 23.59 duration = 0.01 finish = 0.00
Start = 12.00 duration = 48.27 finish = 12.27
EDIT:
It has been noted that this approach may not work for Dr Who and other time travellers. The following shows the necessary changes for those for whom the second law of thermodynamics does not apply:
sprintf( str, "%.2f %.2f", bgn, dur );
int res = 0, cnt = 1, sgn = 1;
for( char *cp = str; ( cp = strtok( cp, " ." ) ) != NULL; cp = NULL, cnt++ )
res += atoi( cp )
* (cnt&1 ? 60 : 1)
* sgn,
sgn = *cp == '-' ? -1 : 1;
/* then one additional test case */
{ 12.00, -2.30 },
/* Output of the single test case: */
Start = 12.00 duration = -2.30 finish = 9.30
Since the first parameter shown in the OP seems to use a 24hr clock, no attempt has been made to test starting at "minus eleven-thirty".
Enjoy your walk. Take the garbage out with you when you leave...
Hi i am an amateur in programing, but i propose me to getting better and because that i start to solve problems in online judges and i don't know how to do a combinatorial analysis, i found some similar question but i can't apply to my code, if you are able to explain me how to do it, i will be incredibly grateful.
so here is the full text of the problem, translated of Portuguese to English. At end is my code.
To prove her scientific skills Princess Bubblegum learned to program using BMO (The best computer in the Candy kingdom) and like every programmer she fell in love with binary numbers.
Because of her addiction to binary numbers she loves decimal numbers that look like a binary number (i.e. a decimal number that contains only digits 0 and 1, for example 101) so given a decimal number N she wants to find a multiple of that number that looks like a number binary, but for some numbers it was taking a long time to find that multiple, even with the help of BMO. Because of her problem-solving addiction, she wasn't doing anything until she found this multiple. Perfect situation for the Earl of Lemongrab, who has taken over the Candy Kingdom. As Finn and Jake, the heroes of the Candy kingdom, can't do anything against the Count and know nothing about multiples, they asked to find the multiples and thus save the kingdom.
Prohibited
The input contains up to 2*10^5 lines, each line with an integer N (0 < N < 10^12), the number Princess Bubblegum wants to find the multiple M (M != 0), this number must be smaller than 10^12, otherwise it doesn't fit in the BMO architecture.
Exit
Print a single integer per line, if there are multiple multiples print the smallest one. If there is no solution print -1
#include <stdlib.h>
#include <math.h>
int main() // normal ways works fine but i have to do it faster, time limit is 2s//
//doing 11 fors works to but its have same tle problem//
{
long long int n, R, num, res, expo;
int b = 0, dig[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, E=0, an, anmax = 1024, reseter, cob, casa;
while (E < 200000)
{
E++;
num = 0;
scanf("%lld", &n); //I have to read a decimal number and from that found the smaller multiple number that is similar to a binary number, and cannot be 0//
res=n%10;
if ((res==1) || (res==0)) // in case the read number is already similar to binary, this works fine//
{ b=1;
for ( num=n;((num>0) && (b==1)); num=num/10)
{
res=num%10;
if ((res==1) || (res==0)){
b=1;
R=n;
}else
{
b=0;
R=-1;
}
}
}else{
if ((n > 0) && (n < 1000000000000))
{
if (n < 500000000000)
{
num = n;
for (expo = -1; num >= 1; expo++, num = num / 10)//so expo is a varieble to found the smaller house of input to made a number, its just for reduce cycles//
{
res = num % 10;
}
if (res > 1)
{
expo = expo + 1;
}
dig[expo] = 1;
R = ((dig[11] * 100000000000) + (dig[10] * 10000000000) + (dig[9] * 1000000000) + (dig[8] * 100000000) + (dig[7] * 10000000) + (dig[6] * 1000000) + (dig[5] * 100000) + (dig[4] * 10000) + (dig[3] * 1000) + (dig[2] * 100) + (dig[1] * 10) + (dig[0] * 1));
for (dig[expo] = 1; ((expo < 11) && (b == 0)); expo++)//// 1 is fixed value until no one of numbers is divisible//
{
anmax = pow(2, expo);//forget this line//
dig[expo] = 1;
for (casa = 0; ((casa < expo) && (b == 0)); casa++)//here is my problem i dont know how to alternate all values that can be ninary//
{ //this is my original idea to solve but this don't generate all possible values//
for (cob = 0; ((cob < 2) && (b == 0)); cob++)
{
dig[casa] = cob;
R = ((dig[11] * 100000000000) + (dig[10] * 10000000000) + (dig[9] * 1000000000) + (dig[8] * 100000000) + (dig[7] * 10000000) + (dig[6] * 1000000) + (dig[5] * 100000) + (dig[4] * 10000) + (dig[3] * 1000) + (dig[2] * 100) + (dig[1] * 10) + (dig[0] * 1));
if ((R % n) == 0)
{
b = 1;
}
}
}
if ((cob == 2) || (b==1))
{
for (reseter = expo; reseter >= 0; reseter--)//it works fine is just to start all values with 0 before its repeats//
{
dig[reseter] = 0;
}
}
}
}
else
{
R = -1;
}
if((R==11111111111) && ((n!=21649) || (n!=513239))){
R=-1; //its not important//
}
}else
{
R=-1;
}
}
// reset para proximos valores//
b = 0;
printf("%lld\n", R);
}
return 0;
}
#include<stdio.h>
void main() {
int nis1 = 0, nis2 = 0, nis5 = 0, nis10 = 0, nis20 = 0, nis50 = 0, nis100 = 0, nis200 = 0;
long int num, count = 0, sum = 0;
while (1)
{
printf_s("what number you like to check? (or press '0' to exit)\n");
scanf_s("%d", &num);
if (num == 0)
break;
for (nis200 = 0; nis200 <= num / 200; nis200++) {
for (nis100 = 0; nis100 <= num / 100; nis100++) {
for (nis50 = 0; nis50 <= num / 50; nis50++) {
for (nis20 = 0; nis20 <= num / 20; nis20++) {
for (nis10 = 0; nis10 <= num / 10; nis10++) {
for (nis5 = 0; nis5 <= num / 5; nis5++) {
for (nis2 = 0; nis2 <= num / 2; nis2++) {
for (nis1 = 0; nis1 <= num; nis1++) {
sum = nis200 * 200 + nis100 * 100 + nis50 * 50 + nis20 * 20 + nis10 * 10 + nis5 * 5 + nis2 * 2 + nis1 * 1;
if (sum == num) {
count++;
break;
}
if (sum > num)
{
break;
}
}
}
}
}
}
}
}
}
printf_s("the number of combinations is: %d\n", count);
count = 0;
}
}
//i have to build a code that with a given number by the user, how many posibillities are there to sum the number with the number:1,2,5,10,20,50,100,200.
Check in each for loop if your sum is already above the num and break the loop if it is the case. Not the ultimate optimization but it makes your code much faster.
You do a lot of counting from 0 to whatever. If you use a number like 500, then your first iteration will be 0 x 200, 0 x 100 ... all the way down to 0 x 2, and then you count 1s from 0 to 500. When you're down to your last option, you should be able to calculate how many 1s you still need.
For any given bill, you always count how many of it you need without regard for the bills you've already selected. If you use a number like 500, and you already have 2 x 200, then you will never need 100 5s; you should be able to calculate the maximum number of 5s you will need. (Keep a running total of each selection-so-far).
I am trying to write a code for calculating the number of trailing zeroes in a factorial of a specific number (large numbers). However, for small numbers, i get the correct result, but for large the deviations keeps increasing. What's wrong with my logic
#include <stdio.h>
int main(void) {
int t;
scanf("%d", &t);
while (t > 0) {
int factorten = 0, factorfive = 0, factortwo = 0, remainingfive = 0,
remainingtwo = 0;
unsigned int factors = 0;
unsigned int n;
scanf("%u", &n);
for (unsigned int i = n; i > 0; i--) {
if (i % 10 == 0) {
factorten++;
continue;
} else if (i % 5 == 0) {
factorfive++;
continue;
} else if (i % 2 == 0) {
// int new = i;
// while(new % 2 == 0)
//{
// new = new / 2;
factortwo++;
//}
continue;
}
}
factors = factors + factorten;
printf("%u\n", factors);
if (factorfive % 2 == 0 && factorfive != 0) {
factors = factors + (factorfive / 2);
} else {
remainingfive = factorfive % 2;
factors = factors + ((factorfive - remainingfive) / 2);
}
printf("%u\n", factors);
if (factortwo % 5 == 0 && factortwo != 0) {
factors = factors + (factortwo / 5);
} else {
remainingtwo = factortwo % 5;
factors = factors + ((factortwo - remainingtwo) / 5);
}
printf("%u\n", factors);
if ((remainingfive * remainingtwo % 10) == 0 &&
(remainingfive * remainingtwo % 10) != 0) {
factors++;
}
printf("%u\n", factors);
t--;
}
}
Sample Input:
6
3
60
100
1024
23456
8735373
Sample Output:
0
14
24
253
5861
2183837
My OUTPUT
0
13
23
235
5394
2009134
Edit: ignore the first two, they are suboptimal. The third algorithm is optimal.
I think this does what you're trying to do, but is a lot simpler and works:
int tzif(int n)
{
int f2 = 0, f5 = 0;
for (;n > 1; n--)
{
int x = n;
for (;x % 2 == 0; x /= 2)
f2++;
for (;x % 5 == 0; x /= 5)
f5++;
}
return f2 > f5 ? f5 : f2;
}
It counts 2-factors and 5-factors of numbers N...2. Then it returns the smaller of the two (because adding 2-factors is useless without adding 5-factors and vice-versa). Your code is too strange for me to analyze.
I think this should work too, because a factorial will have enough 2-factors to "cover" the 5-factors:
int tzif(int n)
{
int f5 = 0;
for (;n > 1; n--)
for (x = n;x % 5 == 0; x /= 5)
f5++;
return f5;
}
This only counts 5-factors and returns that.
Another method I think should work:
int tzif(int n)
{
int f5 = 0;
for (int d = 5; d <= n; d *= 5)
f5 += n / d;
return f5;
}
Count every fifth number (each has a 5-factor), then every 25-th number (each has another 5-factor), etc.
Have 3 counters - c2,c5,c10.
I think the checks should be
divisible by 5 but not by 10 -> c5++
divisible by 2 but not by 10 -> c2++
divisible by 10. Here if true, then count number of 0's. (c10++)
At last number of 0's will be
smaller_of(c2,c5) + c10
Try to code using this. Should work.
First the trailing 0 in N! are determined by factors 2 and 5 (10). The factors 2 always would be more that the factors 5 in this case you only need to calculate how factors 5 are in the N!.
(N!/5) would give you the number of multiple of 5 (5^1) in N!
(N!/25) would give you the number of multiple of 25 (5^2) in N!
(N!/125) would give you the number of multiple of 125 (5^3) in N!
...
(N!/5^n) would give you the number of multiple of 5^n in N!
When you add the multiple of 5 you are adding too the multiple of 25, 125, ..., 5^n, when you add multiple of 25 you are adding too the multiple of 125, ..., 5^n, etc...
In that case you only need to iterate the power of 5 less or equal than N and add the number of multiple of that 5 power.
Code:
long long trailing_zeros(long long N) {
long long zeros = 0;
for (long long power5 = 5; power5 <= N; power5 *= 5)
zeros += N / power5;
return zeros;
}
#include<iostream>
int main()
{
int size,i;
std::cin >> size;
int*fact;
fact = new int[size];
for (i = 0; i < size; i++)
{
std::cin >> fact[size];
}
for (i = 0; i < size; i++)
{
int con = 5;
int multiple = 0;
do
{
multiple = multiple+(fact[size] / con);
con = con * 5;
} while (con < fact[size]);
std::cout << multiple <<'\n';
}
return 0;
}
this code works perfectly for a single input..bt for multiple inputs it prints the o/p for the last entered number...what is wrong..i jst cant think off it
I have 3 IPs and every IP has a weight, I want to return the IP's according to its weights using the random function,,,, for example if we have 3 IP's : X with weight 6,Y with weight 4 and Z with weight 2, I want to return X in 50% of cases and Y in 33% of cases and Z in 17% of cases, depending on random function in C.
This code is to the case of 3 IPs:
double r = rand() / (double)RAND_MAX;
double denom = 6 + 4 + 2;
if (r < 6 / denom) {
// choose X
} else if (r < (6 + 4) / denom) {
// choose Y
} else {
// choose Z
}
what if I have n IPs how can I modify the code to deal with n IPs not a specific number of IPs?
Here is an example of how to do this
Weighted random numbers
and from that post:
int sum_of_weight = 0;
for(int i=0; i<num_choices; i++) {
sum_of_weight += choice_weight[i];
}
int rnd = random(sum_of_weight);
for(int i=0; i<num_choices; i++) {
if(rnd < choice_weight[i])
return i;
rnd -= choice_weight[i];
}
assert(!"should never get here");
Build an array with the cumulative weight of the ip's
Something like this
// C99 code
int pick_ip(int weights[], int nweights)
{
// note you can split this step out if you like (a good plan)
int cum_weights[nweights];
int tot_weight = 0;
for(int i=0; i < nweights; i++)
{
tot_weight += weights[i];
cum_weights[i] = tot_weight;
}
int t = (int)(tot_weight * rand() / (double)RAND_MAX);
if(cum_weights[0] > t) { return 0; }
// binary search for point that we picked
int v = -1;
int l = 0, u = nweights -1;
int m = u/2;
do { // binary search
if(cum_weights[m] > t) u = m;
else l = m;
m = (u + l)/2;
if(cum_weights[l+1] > t) {v=l+1; break;}
if(cum_weights[u-1] <= t) {v=u; break;}
} while(1);
}
Note: if you're doing lots of picking split out the building of the cumulative distribution array. Also if you want floating point weights you need to use a Khan sum to compute the cumulative weights (if you want code for doing that comment and I can add it to my example)