03. Variables, data types, and input — Homework Solutions

The answer .cpp files are in exercises/03/homework/solutions/.

Open this page after trying on your own. Compare your line of reasoning with the How to think about it section, not the code line by line: two pieces of code that look different can both be correct, and what you should imitate is the way of getting there. The Tests section of each problem contains inputs and outputs that have been checked — run your own answer with those inputs before considering yourself done.

Running one of the answers:

g++ -std=c++17 -O2 -o jawab exercises/03/homework/solutions/01-jumlah-dua.cpp
./jawab

Problem 1 — Sum of two numbers

Problem. Read two integers, print their sum, with no extra text.

How to think about it. The standard form of every online judge problem: declare variables, read with cin, print the result with cout. What separates a correct answer from a wrong one here is not the logic but format discipline — a single prompt sentence is enough to make the score zero.

Walkthrough.

int a, b;
cin >> a >> b;
cout << a + b << "\n";

Tests.

Input Output
3 4 7
-5 5 0
1000000000 1000000000 2000000000

The third row is an edge case worth paying attention to: 2 × 10⁹ still fits in an int, but only barely (the limit is 2,147,483,647). If the problem states a limit even slightly higher, the answer must use long long.

Common mistakes.

  • Adding cout << "Masukkan dua bilangan: ";.
  • Printing "Jumlahnya adalah " ("The sum is ") before the number.
  • Using int when the original problem might state a limit of up to 10⁹ for each number; the sum of two numbers that large still fits in an int, but as soon as the limit goes up, switch to long long.

Problem 2 — Average of three scores

Problem. Read three integers, print the average with two decimals.

How to think about it. The trap is integer division. (80 + 85 + 91) / 3 gives 85, not 85.33, because all the numbers are integers. Divide by 3.0 so that C++ computes with fractions. To control the number of decimals, use fixed and setprecision(2) from <iomanip>.

Walkthrough.

int a, b, c;
cin >> a >> b >> c;

double rata = (a + b + c) / 3.0;
cout << fixed << setprecision(2) << rata << "\n";

Tests.

Input Output
7 8 9 8.00
1 1 2 1.33
-3 0 4 0.33

The second row is the most important check: if your answer prints 1.00, the division is still being done as integer division.

Common mistakes.

  • Writing / 3 and then wondering why the result has no decimal point.
  • Using setprecision(2) without fixed. Without fixed, the 2 means "two significant digits", so 85.33 prints as 85.

Problem 3 — Convert seconds

Problem. 3725 seconds becomes 1 2 5.

How to think about it. One hour is 3600 seconds, one minute is 60 seconds. Use / to take the number of large units and % to keep the remainder:

  • hours = total / 3600
  • remainder after hours = total % 3600
  • minutes = remainder / 60
  • seconds = total % 60

Walkthrough.

int total;
cin >> total;

int jam = total / 3600;
int menit = (total % 3600) / 60;
int detik = total % 60;

cout << jam << " " << menit << " " << detik << "\n";

Tests.

Input Output
3725 1 2 5
59 0 0 59
86399 23 59 59

The second row tests the case of less than one minute — the hours and minutes must still be printed as 0, not skipped. The third row tests the value exactly one second before a full day.

Common mistakes.

  • Writing menit = total / 60 without removing the hours first; for 3725 the result is 62, not 2.
  • Forgetting that detik = total % 60 is already correct without an intermediate step, because % 60 is not affected by the hours.

Problem 4 — Last digit and the rest

Problem. 4071 becomes 1 then 407.

How to think about it. Two operations you will use over and over in number theory problems: n % 10 takes the last digit, n / 10 drops it. Combining the two inside a loop is how you process all the digits of a number (Chapter 05).

Walkthrough.

long long n;
cin >> n;

cout << n % 10 << "\n";
cout << n / 10 << "\n";

Tests.

Input Output (two lines)
4071 1 then 407
7 7 then 0
1000 0 then 100

The second row is the edge case of a one-digit number: dropping its last digit leaves 0, not nothing. The third row makes sure the digit 0 is still printed as a valid answer.

Common mistakes.

  • Converting the number to a string to take its last character. It works, but it is longer and easier to get wrong than % 10.
  • Using int for a number that the problem allows up to 10¹⁸.

Challenge — Detecting overflow

Problem. Fix the multiplication whose result is wrong.

How to think about it. 2000000 * 1500000 equals 3 × 10¹², far above the int limit (about 2.1 × 10⁹). The result "wraps around" and prints a nonsensical number without any error message.

What is often missed: changing only the holding variable is not enough.

int a = 2000000, b = 1500000;
long long hasil = a * b;     // still wrong

The multiplication is still computed as int first, and only then is the already-broken result copied into the long long. The correct fix: make the operands long long.

Walkthrough.

long long a = 2000000;
long long b = 1500000;
long long hasil = a * b;

cout << hasil << "\n";       // 3000000000000

If a and b must stay int (for example because they are read from input as int), force one side:

long long hasil = (long long)a * b;

Tests. This program does not read input. After the fix, its output is:

3000000000000

Before the fix, the number is different and may also differ between compilers — that in itself is a hint that what is happening is overflow, not a calculation error.

Common mistakes.

  • Thinking the wrong result means the compiler is broken. The compiler does not check for integer overflow; the program keeps running with the wrong number.
  • Using double as a shortcut. A double only holds about 15 significant digits, so for large integers the result can be off.

OSN-style exercises — walkthrough

The answer files are in exercises/03/osn/solutions/.

Problem 1 — Floor Tiles

How to think about it. Tiles may not be cut, so the number of tiles along the length is P / S with integer division — the fraction really must be discarded, because a tile that is not whole does not count. The same applies to the width. The remaining area is the room area minus the area covered by tiles.

Before writing code, check the size of the result: P and L can be 10⁹, so P × L can reach 10¹⁸. That exceeds int and still fits in long long.

Walkthrough.

long long p, l, s;
cin >> p >> l >> s;

long long banyak = (p / s) * (l / s);
long long sisa = p * l - banyak * s * s;

cout << banyak << " " << sisa << "\n";

Declaring all three as long long from the start removes the need for a cast anywhere.

Tests.

Input Output
10 7 3 6 16
5 5 5 1 0
1000000000 1000000000 7 20408163020408164 11999999964

The second row is an edge case that is easy to miss: a room whose size fits exactly leaves a remainder of zero. The third row is a type check — with int, the output turns into a negative number.

Common mistakes.

  • Computing (p * l) / (s * s). The result is not the number of whole tiles: this approach counts as if the leftover pieces at the two edges could be joined into new tiles.
  • Using int for p and l, so that p * l overflows.

Problem 2 — Final Grade

How to think about it. The answer is fractional, so the computation must be done in double. Writing the weights as 0.3 and 0.4 is enough: one operand of type double makes the whole multiplication be done in double. The output format is fixed with fixed and setprecision(2).

Walkthrough.

int tugas, uts, uas;
cin >> tugas >> uts >> uas;

double akhir = 0.3 * tugas + 0.3 * uts + 0.4 * uas;

cout << fixed << setprecision(2) << akhir << "\n";

fixed means "write in ordinary decimal form, not scientific notation", and setprecision(2) means "two digits after the decimal point". Both come from <iomanip>, which must be included.

Tests.

Input Output
80 75 90 82.50
100 100 100 100.00
0 0 1 0.40

Common mistakes.

  • Writing 30 / 100 * tugas. 30 / 100 is a division of two integers and its result is 0, so the entire final grade becomes zero.
  • Forgetting #include <iomanip>, so the compiler rejects setprecision.
  • Using setprecision(2) without fixed. Without fixed, the 2 means two significant digits — 82.5 prints as 82, and 100 prints as 1e+02.

Problem 3 — Arithmetic Sequence

How to think about it. Two standard formulas:

  • the n-th term: a + (n - 1) × b
  • the sum of n terms: n × (2a + (n - 1) × b) / 2

The second formula is the average of the first and last terms multiplied by the number of terms. The division by 2 always comes out exact, because n × (n − 1) is always even.

Check the sizes: (n − 1) × b can reach 10⁶ × 10⁶ = 10¹², and n × (2a + (n − 1)b) can reach about 10¹⁸. long long is enough, int is not.

Walkthrough.

long long a, b, n;
cin >> a >> b >> n;

long long suku = a + (n - 1) * b;
long long jumlah = n * (2 * a + (n - 1) * b) / 2;

cout << suku << " " << jumlah << "\n";

Tests.

Input Output
3 5 4 18 42
10 -3 5 -2 20
1000000 1000000 1000000 1000000000000 500000500000000000

The second row makes sure a negative difference is handled; the third row is a type check.

Common mistakes.

  • Writing a + n * b for the n-th term. The first term is already a, so the increment is added n − 1 times, not n times.
  • Dividing by 2 too early: n / 2 * (2 * a + (n - 1) * b) is wrong for odd n, because n / 2 discards its fraction first.
  • Using double to be "safe". For a sum as large as 5 × 10¹⁷, double loses the last digits and prints a number that is almost correct — which is still judged wrong.

If you are still stuck

  • Division results are always whole numbers → Chapter 03, section Arithmetic.
  • Large numbers turn negative → Chapter 03, section Why overflow produces a negative number.
  • Unsure how far cin reads → Chapter 03, section Reading input with cin.

Before moving on to Chapter 04, make sure you can answer without running a program: what are the results of 7 / 2, 7 % 2, and (double)7 / 2, and which type is used to hold the sum of 100,000 numbers each with value 10⁹.