Skip to content
CCC Python Course

Formula-plus-condition problems (J1 pattern)

Module
M3.1
Lesson
1 of 1
Reading time
5 min

In this lesson

  • Turn a problem's written rule into a single arithmetic formula.
  • Branch on the formula's result with if/elif/else, choosing the right comparison at each boundary.
  • Print exactly the text a problem asks for, with no extra words or punctuation.

Many of the simplest contest problems follow the same shape. You read a few numbers, combine them with an arithmetic formula, and then branch on the result. This pattern appears in nearly every CCC J1 problem.

From words to a formula

A problem statement describes a rule in plain English. Your job is to turn it into arithmetic.

Imagine you run a shipping company and charge based on both weight and distance. The rule is: base cost is weight times 2 per kilogram, plus distance divided by 10 per 10 kilometres. This is a formula.

Once you have the formula, the second step is to pick the category the result falls into.

Look at this example: if the cost is 20 or less, ship it Standard. If it is more than 20 but at most 50, use Priority. Anything over 50 is Express.

The key is to think of the rule in terms of ranges. Cost is in one of three buckets. Your code checks which bucket it lands in, and prints the label for that bucket.

Computing the result once

You do not repeat the formula. You compute it once, save it in a variable, and then check that variable three times.

Python
kg = int(input())km = int(input())
cost = kg * 2 + km // 10
if cost <= 20:    print("Standard")elif cost <= 50:    print("Priority")else:    print("Express")

The formula is cost = kg * 2 + km // 10. It is computed once at the top. Then the three branches check the value of cost.

The order of the branches matters. if checks first. If that is false, elif checks next. If that is also false, else runs. Because the conditions do not overlap, exactly one branch always runs.

Picking the right boundary

The boundaries are 20 and 50. Any cost at or below 20 goes to Standard. Any cost above 20 and at or below 50 goes to Priority. Anything above 50 goes to Express.

Picking the right comparison operator at each boundary is the heart of this pattern. The problem statement uses words like "at most", "more than", "at least", or "up to". You need to translate each phrase into <, <=, >, or >=.

Here is the trace of the program on three inputs that land right on the boundaries.

Input
1kg = int(input())
2km = int(input())
3
4cost = kg * 2 + km // 10
5
6if cost <= 20:
7 print("Standard")
8elif cost <= 50:
9 print("Priority")
10else:
11 print("Express")
Output so far
(nothing printed yet)
Frames and objects, step 1 of 6FramesGlobal frame
Speed
Python starts at the top of the file. Line 1 runs first.
  • Just changed

Figure 1Shipping cost classified into three tiers by boundary

Read the steps as text

The program reads a package weight and distance, computes a cost, and prints one of three labels. Three presets land exactly on the boundary between labels, showing which branch a tied cost takes.

Cost 20

  1. Python starts at the top of the file. Line 1 runs first.
  2. Line 1 runs: kg is created with the value 10.
  3. Line 2 runs: km is created with the value 0.
  4. Line 4 runs: cost is created with the value 20. cost is computed once, before any branch is checked, so every branch below reads the same value.
  5. Line 6 checks the condition: it is true, so line 7 runs next. cost <= 20 is True only for the first preset. A cost of 20 counts as Standard, not Priority.
  6. Line 7 runs: it prints Standard. The program has finished: no lines are left to run.

Cost 21

  1. Python starts at the top of the file. Line 1 runs first.
  2. Line 1 runs: kg is created with the value 10.
  3. Line 2 runs: km is created with the value 10.
  4. Line 4 runs: cost is created with the value 21. cost is computed once, before any branch is checked, so every branch below reads the same value.
  5. Line 6 checks the condition: it is false, so line 8 runs next. cost <= 20 is True only for the first preset. A cost of 20 counts as Standard, not Priority.
  6. Line 8 checks the condition: it is true, so line 9 runs next. This elif only runs once the if above was False. cost <= 50 covers 21 up to 50.
  7. Line 9 runs: it prints Priority. The program has finished: no lines are left to run.

Cost 51

  1. Python starts at the top of the file. Line 1 runs first.
  2. Line 1 runs: kg is created with the value 25.
  3. Line 2 runs: km is created with the value 10.
  4. Line 4 runs: cost is created with the value 51. cost is computed once, before any branch is checked, so every branch below reads the same value.
  5. Line 6 checks the condition: it is false, so line 8 runs next. cost <= 20 is True only for the first preset. A cost of 20 counts as Standard, not Priority.
  6. Line 8 checks the condition: it is false, so line 11 runs next. This elif only runs once the if above was False. cost <= 50 covers 21 up to 50.
  7. Line 11 runs: it prints Express. A cost of 51 fails both comparisons above, so it falls through to else. The program has finished: no lines are left to run.

When cost is exactly 20, the first branch cost <= 20 is true, so the output is Standard. When cost is 21, the first branch is false, but cost <= 50 is true, so the output is Priority. When cost is 51, both are false, so the output is Express.

The <= operator means less than or equal to. A common mistake is to use < instead. If you write if cost < 20, then cost 20 would fall through to the elif, which is wrong. The problem says "20 or less", so you need <=. Check a few test cases by hand, especially the boundary values themselves, to make sure your comparisons are right.

Why this pattern works

This pattern is fast because it avoids repeated computation. Instead of recalculating the formula in every branch, you compute it once and store the result. On a computer, looking up a value in a variable is nearly free. Computing the same expression multiple times wastes time and introduces risk of typos.

The order of the branches also matters for clarity. By putting the first condition first, you make the code easier to read and debug. When a test case fails, you can manually trace which branch it hit by checking the boundaries in order. If you scrambled the order, the logic becomes hard to follow.

A second example: grade thresholds

Here is another problem with the same pattern. Read a student's percentage mark and output their letter grade. The rule is: 80 or above is A, 70 or above is B, 60 or above is C, 50 or above is D, and below 50 is F.

Python
mark = int(input())
grade_mark = mark
if grade_mark >= 80:    letter = "A"elif grade_mark >= 70:    letter = "B"elif grade_mark >= 60:    letter = "C"elif grade_mark >= 50:    letter = "D"else:    letter = "F"
print(letter)

Notice that this example uses >= (greater than or equal to) instead of <=. The boundaries are different because we are checking thresholds from high to low. A mark of 80 or higher gets an A. If it is not 80 or higher, we check the next threshold. This version uses six branches instead of three, but the pattern is identical: compute once, then branch on the result.

Parsing the exact output

The problem tells you exactly what to print. For the shipping example, the output is one of three words: Standard, Priority, or Express. Nothing else, no explanation, no extra spaces or punctuation.

This is easy to miss. You might think printing "Your tier is Standard" is close enough. It is not. The grader compares your output character by character. If you print even one extra character, the answer is wrong.

When you see a problem that says "print the word" or "output exactly", copy the exact text from the problem into your code. Use print() to output it, and print nothing else.

Common mistakes

Some writers repeat the formula in every branch instead of computing it once: if kg * 2 + km // 10 <= 20: and elif kg * 2 + km // 10 <= 50:. This is error-prone. If you mistype the formula in the second branch, the two branches stop agreeing on what "cost" means. Store the result in a variable and check that variable instead. The code gets shorter, and if you need to revise the formula later, you only change it in one place.

The comparison operator at each boundary is the other place mistakes creep in. The problem says "20 or less", so you need <=, not <. Read the boundary words carefully: "at most" and "or less" both mean <=, "more than" and "greater than" mean >, and "at least" and "or above" mean >=. Test your code on the boundary values themselves, exactly 20 and exactly 50, by hand: write down what you expect it to print, then run it and compare.

The output itself is a third place to slip up. The grader compares your output byte for byte, so if the problem says to print "Standard", print exactly that word and nothing else. Do not add "Your tier is Standard" or "Tier: Standard" or any extra punctuation. When in doubt, look at the sample output and copy it exactly, including capitalization and spacing.

Practice

Try these on the judges. Each link opens the problem on WMOJ or DMOJ.

  1. 2022 J1
    Cupcake Party (opens on WMOJ in a new tab) WMOJ

    Work out a fair price for a shared batch of cupcakes.

  2. 2021 J1
    Boiling Water (opens on WMOJ in a new tab) WMOJ

    Decide how long a kettle needs before water is ready.

  3. 2014 J1
    Triangle Times (opens on DMOJ in a new tab) DMOJ

    Classify a triangle as acute, right, or obtuse from its three angles.

    Why DMOJ: One of the earliest J1 problems, and still a plain formula-then-branch shape.