Lab 1 to 6 (18 Hours)

 

Problem Statement

This is one of the simplest problems in competitive programming.

You are required to print:

Hello World!

No input is given, and no processing is required.


Input Format

There is no input.


Output Format

Print exactly:

Hello World!

including correct capitalization and punctuation.


Key Idea

This problem is purely for:

  • Checking environment setup
  • Understanding input/output handling
  • Getting familiar with an online judge

There is no algorithm involved.


Algorithm

1.      Print the string "Hello World!"

2.      End program


Time Complexity

O(1)


C++ Solution (OOP Style)

Even though this problem does not require OOP, we can structure it using a class for practice.

#include <iostream>

using namespace std;

 

class HelloWorld {

public:

    void printMessage() {

        cout << "Hello World!" << endl;

    }

};

int main() {

    HelloWorld hw;

    hw.printMessage();

 

    return 0;

}


Explanation

Step 1: Create class

class HelloWorld

This class represents a simple message printer.


Step 2: Define method

void printMessage()

This function prints the required output.


Step 3: Create object and call method

HelloWorld hw;

hw.printMessage();


Output

Hello World!


OOP Concepts Used

  • Class: HelloWorld
  • Public method: printMessage()
  • Object creation
  • Encapsulation (basic structure)

Why this problem exists

This problem from Kattis is used to:

  • Verify submission setup
  • Test compiler configuration
  • Introduce beginners to online judging systems

Conclusion

Although trivial, this problem is the starting point of all competitive programming journeys and ensures that the coding environment is correctly configured before solving more complex problems.

Problem Statement

A boy wants to divide a watermelon of weight w kilograms into two parts such that:

  • Both parts have positive integer weights.
  • Both parts have even weights.

Determine whether this is possible.


Example 1

Input

8

Output

YES

Explanation

8 = 4 + 4

Both parts have even weights.


Example 2

Input

6

Output

YES

Explanation

6 = 2 + 4


Example 3

Input

2

Output

NO

Explanation

The only possible division is:

2 = 1 + 1

Both parts are odd, so the answer is NO.


Example 4

Input

5

Output

NO

Since 5 is an odd number, it cannot be divided into two even integers.


Key Observation

Two even numbers always add up to an even number.

Therefore:

  • If w is odd → Impossible.
  • If w = 2 → Impossible.
  • Otherwise → Possible.

Hence, the required condition is:

w > 2 && w % 2 == 0


Algorithm

1.      Read the value of w.

2.      Create an object of the Watermelon class.

3.      Call the member function canDivide().

4.      If it returns true, print YES.

5.      Otherwise, print NO.


Time Complexity

O(1)

Only one condition is checked.


OOP Solution in C++

#include <iostream>

using namespace std;

 

class Watermelon {

private:

    int weight;

 

public:

    // Constructor

    Watermelon(int w) {

        weight = w;

    }

 

    // Member function

    bool canDivide() {

        return (weight > 2 && weight % 2 == 0);

    }

};

 

int main() {

    int w;

    cin >> w;

 

    Watermelon wm(w);

 

    if (wm.canDivide())

        cout << "YES" << endl;

    else

        cout << "NO" << endl;

 

    return 0;

}


Explanation of the Program

Step 1

Read the watermelon weight.

int w;

cin >> w;


Step 2

Create a Watermelon object.

Watermelon wm(w);

The constructor stores the value of w inside the object.


Step 3

Call the member function.

wm.canDivide();

The function checks:

weight > 2 && weight % 2 == 0

If both conditions are true, it returns true; otherwise, it returns false.


Step 4

Display the answer.

if (wm.canDivide())

    cout << "YES";

else

    cout << "NO";


Dry Run

Example 1

Input

8

Execution

weight = 8

 

8 > 2      → True

8 % 2 == 0 → True

 

Output → YES


Example 2

Input

2

Execution

weight = 2

 

2 > 2 → False

 

Output → NO


Example 3

Input

7

Execution

weight = 7

 

7 % 2 == 1

 

Output → NO


OOP Concepts Used

  • Class – Watermelon
  • Private Data Member – weight
  • Constructor – Initializes the object's weight.
  • Member Function – canDivide() checks the required condition.
  • Object Creation – Watermelon wm(w);
  • Encapsulation – The weight is kept private and accessed through a public member function.

Why w > 2?

Consider these examples:

4 = 2 + 2  

6 = 2 + 4  

8 = 4 + 4  

10 = 2 + 8 

But:

2 = 1 + 1  

The two parts are odd, so the answer is NO.


Common Mistake

Incorrect solution:

if (weight % 2 == 0)

    cout << "YES";

This prints YES for weight = 2, which is incorrect.

Correct solution:

if (weight > 2 && weight % 2 == 0)


Final Rule

A watermelon can be divided into two positive even-weight parts if and only if:

weight > 2 && weight % 2 == 0


Problem Statement

Sometimes words like "localization" or "internationalization" are too long to write repeatedly. To make writing easier, a long word is abbreviated as follows:

  • Keep the first character.
  • Replace the middle characters with the number of omitted characters.
  • Keep the last character.

For example:

  • localization → l10n
  • internationalization → i18n

Given n words, abbreviate each word if its length is greater than 10. Otherwise, print the word unchanged.


Input Format

  • The first line contains an integer n (the number of words).
  • Each of the next n lines contains one word.

Output Format

For each word:

  • If its length is 10 or less, print it unchanged.
  • Otherwise, print its abbreviation.

Sample Input

4

word

localization

internationalization

apple

Sample Output

word

l10n

i18n

apple


Explanation

Word 1

word

Length = 4

Since the length is less than or equal to 10, print it as it is.

Output:

word


Word 2

localization

Length = 12

  • First letter = l
  • Middle letters = 10
  • Last letter = n

Output:

l10n


Word 3

internationalization

Length = 20

  • First letter = i
  • Middle letters = 18
  • Last letter = n

Output:

i18n


Key Observation

For every word:

  • If length ≤ 10, print the original word.
  • Otherwise,

First Letter + (Length − 2) + Last Letter


Algorithm

1.     Read integer n.

2.     Repeat n times:

o    Read a word.

o    Find its length.

o    If the length is greater than 10:

§  Print the first character.

§  Print length - 2.

§  Print the last character.

o    Otherwise, print the original word.


Time Complexity

For each word, only its length is checked.

Overall complexity:

O(n)

where n is the number of words.


OOP Solution in C++

#include <iostream>

#include <string>

using namespace std;

 

class WordAbbreviator {

private:

    string word;

 

public:

    // Constructor

    WordAbbreviator(string w) {

        word = w;

    }

 

    // Member function

    string abbreviate() {

        if (word.length() <= 10)

            return word;

 

        return word[0] + to_string(word.length() - 2) + word[word.length() - 1];

    }

};

 

int main() {

    int n;

    cin >> n;

 

    while (n--) {

        string s;

        cin >> s;

 

        WordAbbreviator obj(s);

        cout << obj.abbreviate() << endl;

    }

 

    return 0;

}


Explanation of the Program

Step 1

Read the number of words.

int n;

cin >> n;


Step 2

Read each word.

string s;

cin >> s;


Step 3

Create an object.

WordAbbreviator obj(s);

The constructor stores the word inside the object.


Step 4

Call the member function.

obj.abbreviate();

If the word length is more than 10, the function returns

First Character + Length − 2 + Last Character

Otherwise, it returns the original word.


Dry Run

Input

localization

Length = 12

First Character = l

Middle Characters = 10

Last Character = n

Output

l10n


Input

apple

Length = 5

Since length ≤ 10,

Output

apple


OOP Concepts Used

  • Class – WordAbbreviator
  • Private Data Member – word
  • Constructor – Initializes the object with a word.
  • Public Member Function – abbreviate()
  • Object Creation
  • Encapsulation

Common Mistakes

Incorrect

Using:

word.length() - 1

instead of

word.length() - 2

The abbreviation should count only the omitted middle characters.


Incorrect

Abbreviating every word regardless of length.

Words with 10 or fewer characters must remain unchanged.


Final Rule

If

Length ≤ 10

Print the original word.

Otherwise print

First Character + (Length − 2) + Last Character


Conclusion

This problem introduces beginners to:

  • String manipulation
  • Conditional statements
  • Loops
  • Object-Oriented Programming (OOP)
  • Constructors
  • Member functions
  • Encapsulation

Although the problem can be solved with a few lines of code, implementing it using OOP helps students practice designing classes and member functions while solving competitive programming problems.

Problem Statement

Three friends, Petya, Vasya, and Tonya, are preparing for a programming contest. They have n problems to solve.

For each problem:

  • Each friend either knows the solution (1) or does not know the solution (0).
  • The team will solve a problem only if at least two of the three friends are sure about the solution.

Your task is to determine how many problems the team will solve.


Input Format

  • The first line contains an integer n — the number of problems.
  • Each of the next n lines contains three integers (0 or 1), representing whether Petya, Vasya, and Tonya know the solution.

Output Format

Print a single integer — the number of problems the team will solve.


Sample Input

3

1 1 0

1 1 1

1 0 0

Sample Output

2


Explanation

Problem 1

1 1 0

Two students know the solution.

The team solves it.


Problem 2

1 1 1

All three students know the solution.

The team solves it.


Problem 3

1 0 0

Only one student knows the solution.

The team does not solve it.

Therefore, the answer is

2


Key Observation

For every problem,

Calculate

Petya + Vasya + Tonya

If the sum is 2 or 3, the team will solve the problem.


Algorithm

1.     Read integer n.

2.     Initialize count = 0.

3.     Repeat n times:

o    Read three integers.

o    Calculate their sum.

o    If the sum is at least 2, increment count.

4.     Print count.


Time Complexity

Each problem is processed once.

Time Complexity: O(n)

Space Complexity: O(1)


OOP Solution in C++

#include <iostream>

using namespace std;

 

class TeamDecision {

private:

    int petya, vasya, tonya;

 public:

    // Constructor

    TeamDecision(int p, int v, int t) {

        petya = p;

        vasya = v;

        tonya = t;

    }

 

    // Member function

    bool canSolve() {

        return (petya + vasya + tonya >= 2);

    }

};

 

int main() {

    int n;

    cin >> n;

 

    int solved = 0;

 

    while (n--) {

        int p, v, t;

        cin >> p >> v >> t;

 

        TeamDecision problem(p, v, t);

 

        if (problem.canSolve())

            solved++;

    }

 

    cout << solved << endl;

 

    return 0;

}


Explanation of the Program

Step 1

Read the number of problems.

int n;

cin >> n;


Step 2

For each problem, read the three values.

int p, v, t;

cin >> p >> v >> t;


Step 3

Create an object.

TeamDecision problem(p, v, t);

The constructor stores the three values inside the object.


Step 4

Call the member function.

problem.canSolve();

The function checks

petya + vasya + tonya >= 2

If true, the function returns true.


Step 5

Increase the answer.

if(problem.canSolve())

    solved++;

Finally,

cout << solved;

prints the total number of solved problems.


Dry Run

Sample Input

3

1 1 0

1 1 1

1 0 0

Problem 1

1 + 1 + 0 = 2

Team solves it.

Current Answer = 1


Problem 2

1 + 1 + 1 = 3

Team solves it.

Current Answer = 2


Problem 3

1 + 0 + 0 = 1

Less than 2.

Team cannot solve it.

Final Answer =

2


OOP Concepts Used

  • Class – TeamDecision
  • Private Data Members – petya, vasya, tonya
  • Constructor – Initializes the object's data.
  • Public Member Function – canSolve()
  • Object Creation
  • Encapsulation

Common Mistakes

Mistake 1

Using

petya + vasya + tonya > 2

This ignores cases where exactly 2 students know the solution.

Correct condition:

petya + vasya + tonya >= 2


Mistake 2

Printing the result for every problem instead of counting the total number of solvable problems.

The problem asks for one final count, not individual outputs.


Final Rule

For every problem,

If (Petya + Vasya + Tonya ≥ 2)

        Solve the problem

Else

        Skip the problem


Conclusion

This problem helps beginners practice:

  • Input and output
  • Loops
  • Conditional statements
  • Counting techniques
  • Object-Oriented Programming (OOP)
  • Constructors
  • Member functions
  • Encapsulation

 

Problem Statement

You are given a variable x, initially set to 0.

You are given n statements. Each statement is one of the following:

  • ++X or X++ → increment x by 1
  • --X or X-- → decrement x by 1

Your task is to compute the final value of x after executing all statements.


Input Format

  • The first line contains an integer n — number of statements.
  • Each of the next n lines contains one statement.

Output Format

Print the final value of x.


Sample Input

3

X++

++X

X--

Sample Output

1


Explanation

Initial value:

x = 0

Step 1

X++ → x = 1

Step 2

++X → x = 2

Step 3

X-- → x = 1

Final answer:

1


Key Observation

  • If the string contains "++" → increment
  • If the string contains "--" → decrement

We do not need to care about the position of X.


Algorithm

1.     Initialize x = 0

2.     Read n

3.     For each statement:

o    If it contains "++" → x++

o    Else → x--

4.     Print x


Time Complexity

O(n)

Each statement is processed once.


OOP Solution in C++

#include <iostream>

#include <string>

using namespace std;

 

class BitCounter {

private:

    int x;

 

public:

    // Constructor

    BitCounter() {

        x = 0;

    }

 

    // Process one statement

    void apply(string s) {

        if (s.find("++") != string::npos)

            x++;

        else

            x--;

    }

 

    int getValue() {

        return x;

    }

};

 

int main() {

    int n;

    cin >> n;

 

    BitCounter counter;

 

    while (n--) {

        string s;

        cin >> s;

        counter.apply(s);

    }

 

    cout << counter.getValue() << endl;

 

    return 0;

}


Explanation of the Program

Step 1: Initialize

BitCounter counter;

Sets:

x = 0


Step 2: Read each operation

string s;

cin >> s;


Step 3: Apply operation

counter.apply(s);

Inside function:

  • If "++" exists → increment
  • Else → decrement

Step 4: Output result

cout << counter.getValue();


Dry Run

Input

3

X++

++X

X--

Execution

x = 0

 

X++ → 1

++X → 2

X-- → 1

Output

1


OOP Concepts Used

  • Class → BitCounter
  • Private Member Variable → x
  • Constructor → initializes x
  • Member Functions → apply(), getValue()
  • Encapsulation → x is protected inside class

Common Mistakes

Mistake 1

Checking full string equality:

if (s == "X++")

This misses cases like ++X.

Correct approach:

if (s.find("++") != string::npos)


Mistake 2

Forgetting initial value:

x must start from 0


Final Rule

For each statement:

if contains "++" → x++

else → x--


Conclusion

This problem is a simple introduction to:

  • String handling
  • Conditional logic
  • Looping
  • Counting operations
  • Object-Oriented Programming (OOP)

Problem Statement

You are given a 5 × 5 matrix containing only 0s and exactly one 1.

Your task is to move the 1 to the center of the matrix (position (3,3) in 1-based indexing) using the minimum number of moves.

In one move, you can swap adjacent rows or columns (equivalent to moving the 1 up, down, left, or right by 1 step).

Return the minimum number of moves required.


Input Format

  • 5 lines, each containing 5 integers (0 or 1).
  • Exactly one cell contains 1.

Output Format

Print a single integer — the minimum number of moves.


Key Observation

The problem is simply the Manhattan distance between:

  • Current position of 1: (i, j)
  • Target position: (3, 3)

So:

moves = |i - 3| + |j - 3|


Algorithm

1.     Read the 5×5 matrix.

2.     Find the position (i, j) of 1.

3.     Compute Manhattan distance to (3, 3).

4.     Print the result.


Time Complexity

O(25) = O(1)


OOP Solution in C++

#include <iostream>

using namespace std;

 

class BeautifulMatrix {

private:

    int matrix[5][5];

    int row, col;

 

public:

    // Constructor

    BeautifulMatrix() {

        row = col = 0;

    }

 

    // Input matrix and locate 1

    void readMatrix() {

        for (int i = 0; i < 5; i++) {

            for (int j = 0; j < 5; j++) {

                cin >> matrix[i][j];

                if (matrix[i][j] == 1) {

                    row = i;

                    col = j;

                }

            }

        }

    }

 

    // Compute minimum moves

    int getMoves() {

        return abs(row - 2) + abs(col - 2);

    }

};

 

int main() {

    BeautifulMatrix bm;

 

    bm.readMatrix();

 

    cout << bm.getMoves() << endl;

 

    return 0;

}


Explanation

Step 1: Read matrix

The program scans all 25 elements and finds where 1 is located.


Step 2: Store position

row = i;

col = j;

This records the location of the target element.


Step 3: Compute distance

Center of matrix (0-based indexing):

(2, 2)

So we compute:

|row - 2| + |col - 2|


Example

Input

0 0 0 0 0

0 0 0 0 0

0 0 1 0 0

0 0 0 0 0

0 0 0 0 0

Position of 1

(2, 2)

Moves

|2 - 2| + |2 - 2| = 0

Output

0


OOP Concepts Used

  • Class: BeautifulMatrix
  • Private data members: matrix, row, col
  • Constructor: initializes variables
  • Member functions:
    • readMatrix()
    • getMoves()
  • Encapsulation: matrix handling inside class

Common Mistakes

  • Forgetting that indexing is 0-based in C++
  • Using (3,3) instead of (2,2)
  • Not storing the position of 1 correctly

Final Rule

Answer = |row - 2| + |col - 2|


Conclusion

This problem is a classic introduction to grid problems and teaches:

  • Matrix traversal
  • Coordinate geometry in grids
  • Manhattan distance
  • Basic object-oriented design in C++

 

 

 

 

 

 

Problem Statement

In a programming contest, participants are ranked by score in non-increasing order (sorted from highest to lowest).

A participant advances to the next round if:

  • Their score is greater than 0, and
  • Their score is greater than or equal to the score of the participant in k-th place

Given the number of participants and their scores, determine how many advance to the next round.


Input Format

  • First line: two integers n and k
    • n = number of participants
    • k = position threshold
  • Second line: n integers representing scores in non-increasing order

Output Format

Print a single integer — number of participants who advance.


Key Idea

Let the score of the k-th participant be:

threshold = a[k - 1]

A participant advances if:

  • score > 0
  • score >= threshold

Algorithm

1.     Read n and k

2.     Read array of scores

3.     Set threshold = score[k - 1]

4.     Count all scores satisfying:

o    score >= threshold

o    score > 0

5.     Print count


Time Complexity

O(n)

Only one pass through the array.


OOP Solution in C++

#include <iostream>

#include <vector>

using namespace std;

 

class NextRound {

private:

    vector<int> scores;

    int k;

    int threshold;

 

public:

    // Constructor

    NextRound(vector<int> s, int kk) {

        scores = s;

        k = kk;

        threshold = scores[k - 1];

    }

 

    // Compute number of qualifiers

    int countQualifiers() {

        int count = 0;

 

        for (int x : scores) {

            if (x >= threshold && x > 0)

                count++;

        }

 

        return count;

    }

};

 

int main() {

    int n, k;

    cin >> n >> k;

 

    vector<int> arr(n);

 

    for (int i = 0; i < n; i++)

        cin >> arr[i];

 

    NextRound contest(arr, k);

 

    cout << contest.countQualifiers() << endl;

 

    return 0;

}


Explanation

Step 1: Read input

int n, k;

cin >> n >> k;


Step 2: Store scores

vector<int> arr(n);


Step 3: Find threshold score

threshold = scores[k - 1];

This is the score of the k-th ranked participant.


Step 4: Count eligible participants

A participant qualifies if:

score >= threshold && score > 0


Example

Input

8 5

10 9 8 7 7 7 5 5

Threshold

k = 5 → threshold = 7

Valid scores

10

9 

8 

7 

7 

7 

5  (less than 7)

5  (less than 7)

Output

6


OOP Concepts Used

  • Class: NextRound
  • Private data members: scores, k, threshold
  • Constructor: initializes threshold
  • Member function: countQualifiers()
  • Encapsulation of logic inside class

Common Mistakes

  • Forgetting to exclude scores equal to 0
  • Using k instead of k - 1 (indexing error)
  • Not handling boundary conditions properly

Final Rule

A participant qualifies if:

score >= score[k - 1] AND score > 0


Conclusion

This problem is an important introduction to:

  • Array processing
  • Sorting assumptions
  • Threshold-based filtering
  • Basic OOP design in C++

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Problem Statement

Petya loves comparing strings, but he is not sure about case sensitivity.

Given two strings, determine their lexicographical comparison ignoring case.

  • If the first string is less than the second → print -1
  • If the first string is greater than the second → print 1
  • If both are equal → print 0

The comparison is case-insensitive, meaning uppercase and lowercase letters are treated as the same.


Input Format

  • Two strings are given, each on a separate line.

Output Format

Print:

  • -1, 0, or 1 based on comparison.

Key Idea

Convert both strings to the same case (lowercase or uppercase), then compare them lexicographically.


Algorithm

1.      Read two strings a and b

2.      Convert both to lowercase

3.      Compare:

o    If a < b → print -1

o    If a > b → print 1

o    Else → print 0


Time Complexity

O(n) where n is length of the strings.


OOP Solution in C++

#include <iostream>

#include <string>

using namespace std;

 

class StringCompare {

private:

    string a, b;

 

    string toLowerCase(string s) {

        for (char &c : s) {

            if (c >= 'A' && c <= 'Z')

                c = c + 32;

        }

        return s;

    }

 

public:

    // Constructor

    StringCompare(string s1, string s2) {

        a = toLowerCase(s1);

        b = toLowerCase(s2);

    }

 

    int compare() {

        if (a < b) return -1;

        if (a > b) return 1;

        return 0;

    }

};

 

int main() {

    string s1, s2;

    cin >> s1 >> s2;

 

    StringCompare obj(s1, s2);

 

    cout << obj.compare() << endl;

 

    return 0;

}


Explanation

Step 1: Read input

string s1, s2;

cin >> s1 >> s2;


Step 2: Convert to lowercase

if (c >= 'A' && c <= 'Z')

    c = c + 32;

This ensures case-insensitive comparison.


Step 3: Compare strings

if (a < b) return -1;

if (a > b) return 1;

Lexicographical comparison works directly in C++ strings.


Example

Input

aaaa

aaaA

After conversion

aaaa

aaaa

Output

0


OOP Concepts Used

  • Class: StringCompare
  • Private data members: a, b
  • Constructor: initializes processed strings
  • Private helper function: toLowerCase()
  • Member function: compare()
  • Encapsulation of logic

Common Mistakes

  • Forgetting case conversion
  • Using ASCII comparison without normalization
  • Comparing original strings directly

Final Rule

Convert both strings to lowercase → compare lexicographically


Conclusion

This problem is a simple but important introduction to:

  • String manipulation
  • ASCII operations
  • Lexicographical comparison
  • Object-oriented programming design in C++

 

 

Problem Statement

You are given several integers. For each integer, determine whether it is even or odd.

For every number:

  • If it is even → print "even"
  • If it is odd → print "odd"

Input Format

  • First line contains an integer n, the number of test cases.
  • The next n lines each contain a single integer.

Output Format

For each integer, print either:

  • even
  • odd

on a separate line.


Key Idea

A number is:

  • Even if number % 2 == 0
  • Odd otherwise

Algorithm

  1. Read integer n
  2. Repeat n times:
    • Read number x
    • If x % 2 == 0, print "even"
    • Else print "odd"

Time Complexity

O(n)

Each number is processed once.


C++ Solution (OOP Style)

#include <iostream>

using namespace std;

 

class OdditiesChecker {

private:

    int value;

 

public:

    // Constructor

    OdditiesChecker(int v) {

        value = v;

    }

 

    string check() {

        if (value % 2 == 0)

            return "even";

        else

            return "odd";

    }

};

 

int main() {

    int n;

    cin >> n;

 

    while (n--) {

        int x;

        cin >> x;

 

        OdditiesChecker obj(x);

        cout << obj.check() << endl;

    }

 

    return 0;

}


Explanation

Step 1: Read input count

int n;

cin >> n;


Step 2: Process each number

int x;

cin >> x;


Step 3: Create object

OdditiesChecker obj(x);

Encapsulates the value inside a class.


Step 4: Check parity

obj.check();

Logic:

if value % 2 == 0 → even

else → odd


Example

Input

3

10

7

0

Output

even

odd

even


OOP Concepts Used

  • Class: OdditiesChecker
  • Private data member: value
  • Constructor: initializes value
  • Member function: check()
  • Encapsulation of logic inside object

Common Mistakes

  • Forgetting modulo operation % 2
  • Printing integers instead of strings
  • Not handling zero correctly (0 is even)

Final Rule

If value % 2 == 0 → even

Else → odd


Conclusion

This problem is a basic introduction to:

  • Conditional logic
  • Modulo arithmetic
  • Simple input/output handling
  • Object-oriented programming structure in C++

 

 

 

 

 

 

 

 

 

Problem Statement

In this problem, you are given a compound name written in the format:

Word1-Word2-Word3-...-WordN

Your task is to create an abbreviation by taking the first letter of each word and concatenating them together.


Input Format

A single line containing a string with words separated by hyphens (-).


Output Format

Print the abbreviation formed by the first letter of each word.


Example

Input

Knuth-Morris-Pratt

Output

KMP


Another Example

Input

Portable-Network-Graphics

Output

PNG


Key Idea

We only need to:

  • Split the string by -
  • Take the first character of each segment
  • Combine them

Algorithm

  1. Read input string s
  2. Initialize an empty result string
  3. Traverse the string:
    • If current character is the first character OR previous character is -, take it
  4. Print the result

Time Complexity

O(n) where n is the length of the string.


C++ Solution (OOP Style)

#include <iostream>

using namespace std;

 

class Autori {

private:

    string s;

 

public:

    // Constructor

    Autori(string str) {

        s = str;

    }

 

    string getAbbreviation() {

        string result = "";

 

        for (int i = 0; i < s.length(); i++) {

            if (i == 0 || s[i - 1] == '-') {

                result += s[i];

            }

        }

 

        return result;

    }

};

 

int main() {

    string input;

    cin >> input;

 

    Autori obj(input);

 

    cout << obj.getAbbreviation() << endl;

 

    return 0;

}


Explanation

Step 1: Read input

string input;

cin >> input;


Step 2: Create object

Autori obj(input);

Stores the full string inside the class.


Step 3: Extract abbreviation

if (i == 0 || s[i - 1] == '-')

    result += s[i];

We take:

  • First character of the string
  • Characters after every -

Step 4: Output result

cout << obj.getAbbreviation();


Example Walkthrough

Input

Portable-Network-Graphics

Processing

Word

First letter

Portable

P

Network

N

Graphics

G

Output

PNG


OOP Concepts Used

  • Class: Autori
  • Private data member: s
  • Constructor: initializes string
  • Member function: getAbbreviation()
  • Encapsulation of string processing logic

Common Mistakes

  • Forgetting to check i == 0
  • Splitting incorrectly with spaces instead of -
  • Not handling single-word input properly

Final Rule

Take the first character of the string and every character that follows a '-'


Conclusion

This problem is a simple string manipulation task that helps beginners learn:

  • String traversal
  • Character-based parsing
  • Basic pattern extraction
  • Object-oriented programming structure in C++

Problem Statement

You are given three integers. However, their order is unknown.

You are also given a string containing the characters:

A B C

The task is:

  • Sort the three numbers in ascending order
  • Then rearrange them according to the given pattern string

For example, if the sorted numbers are:

x ≤ y ≤ z

and the string is "CBA", the output should be:

z y x


Input Format

  • First line: three integers
  • Second line: a string of length 3 containing only A, B, C

Output Format

Print the three numbers in the order specified by the string.


Key Idea

  1. Sort the three numbers.
  2. Map:
    • A → smallest
    • B → middle
    • C → largest
  3. Output according to the given pattern.

Algorithm

  1. Read three integers into an array
  2. Sort the array
  3. Read the pattern string
  4. For each character in the string:
    • Print corresponding number
  5. Print result

Time Complexity

O(1) (since only 3 numbers are involved)


C++ Solution (OOP Style)

#include <iostream>

#include <algorithm>

using namespace std;

 

class ABCSorter {

private:

    int arr[3];

    string pattern;

 

public:

    // Constructor

    ABCSorter(int a, int b, int c, string p) {

        arr[0] = a;

        arr[1] = b;

        arr[2] = c;

        pattern = p;

 

        sort(arr, arr + 3);

    }

 

    void printOrdered() {

        for (char ch : pattern) {

            if (ch == 'A')

                cout << arr[0] << " ";

            else if (ch == 'B')

                cout << arr[1] << " ";

            else if (ch == 'C')

                cout << arr[2] << " ";

        }

    }

};

 

int main() {

    int a, b, c;

    cin >> a >> b >> c;

 

    string p;

    cin >> p;

 

    ABCSorter obj(a, b, c, p);

    obj.printOrdered();

 

    return 0;

}


Explanation

Step 1: Read input

int a, b, c;

cin >> a >> b >> c;


Step 2: Sort values

sort(arr, arr + 3);

Now:

  • arr[0] = smallest
  • arr[1] = middle
  • arr[2] = largest

Step 3: Read pattern

string p;

cin >> p;


Step 4: Print based on pattern

if (ch == 'A') → smallest

if (ch == 'B') → middle

if (ch == 'C') → largest


Example

Input

6 4 2

ABC

Sorted

2 4 6

Output

2 4 6


Input

6 4 2

CBA

Output

6 4 2


OOP Concepts Used

  • Class: ABCSorter
  • Private data members: arr, pattern
  • Constructor: initializes and sorts data
  • Member function: printOrdered()
  • Encapsulation of sorting logic

Common Mistakes

  • Forgetting to sort the array
  • Misinterpreting mapping of A, B, C
  • Printing without spaces or in wrong order

Final Rule

A → smallest

B → middle

C → largest


Conclusion

This problem teaches:

  • Sorting basics
  • Index mapping
  • Simple permutation logic
  • Object-oriented programming structure in C++

 

 

 

 

 

 

 

 

 

 

 

 

 

Problem Statement

In baseball statistics, a player’s performance is measured using an average.

You are given n at-bats, where each at-bat is either:

  • A number representing the number of bases gained (0–4), or
  • -1 which means the player did not bat (this should be ignored)

Your task is to compute the player's slugging percentage, defined as:

slugging percentage = (sum of valid bases) / (number of valid at-bats)

Ignore all -1 values.


Input Format

  • First line: integer n
  • Second line: n integers representing at-bats

Output Format

Print the slugging percentage as a floating-point number.


Key Idea

We only consider values not equal to -1.

So:

  • Sum all valid values
  • Count valid entries
  • Divide sum by count

Algorithm

  1. Read integer n
  2. Initialize:
    • sum = 0
    • count = 0
  3. For each value:
    • If value != -1:
      • add to sum
      • increment count
  4. Print sum / count

Time Complexity

O(n)


C++ Solution (OOP Style)

#include <iostream>

using namespace std;

 

class BatterUp {

private:

    int n;

    int arr[100];

 

public:

    // Constructor

    BatterUp(int size) {

        n = size;

    }

 

    void readInput() {

        for (int i = 0; i < n; i++) {

            cin >> arr[i];

        }

    }

 

    double calculateSlugging() {

        int sum = 0;

        int count = 0;

 

        for (int i = 0; i < n; i++) {

            if (arr[i] != -1) {

                sum += arr[i];

                count++;

            }

        }

 

        return (double)sum / count;

    }

};

 

int main() {

    int n;

    cin >> n;

 

    BatterUp player(n);

    player.readInput();

 

    cout << player.calculateSlugging() << endl;

 

    return 0;

}


Explanation

Step 1: Read input

int n;

cin >> n;


Step 2: Store values

cin >> arr[i];

We store all at-bats in an array.


Step 3: Ignore invalid values

if (arr[i] != -1)

We skip all -1 entries.


Step 4: Compute average

(double)sum / count

We cast to double to ensure floating-point division.


Example

Input

5

3 2 -1 4 1

Valid values

3 + 2 + 4 + 1 = 10

count = 4

Output

2.5


OOP Concepts Used

  • Class: BatterUp
  • Private data members: n, arr
  • Constructor: initializes size
  • Member functions:
    • readInput()
    • calculateSlugging()
  • Encapsulation of logic

Common Mistakes

  • Including -1 in calculations
  • Forgetting type casting to double
  • Division by zero (if all values are -1 — though not in constraints)

Final Rule

Ignore -1 values, then compute average of remaining numbers


Conclusion

This problem is a simple introduction to:

  • Filtering invalid data
  • Basic statistics (average)
  • Array processing
  • Object-oriented programming in C++

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Problem Statement

You are given a stream of integers. After reading each new integer, you must output the median of all numbers seen so far.

  • If the count of numbers is odd → median is the middle element
  • If the count is even → median is the average of the two middle elements (integer division is not used; use float/double)

Input Format

  • A sequence of integers, one per line
  • Input ends at EOF

Output Format

For each input number, print the current median.


Key Idea

Maintain a sorted structure of all numbers seen so far and compute median dynamically.

Efficient approach (ICPC standard):

  • Use two heaps:
    • Max-heap for lower half
    • Min-heap for upper half

But for beginner level, we can use a sorted array (simple but slower).


Simple Algorithm (Beginner Version)

  1. Read numbers one by one
  2. Insert into a list/vector
  3. Sort the list
  4. Compute median:
    • If odd → middle element
    • If even → average of two middle elements
  5. Print result

Time Complexity

  • Naive approach: O(n² log n) (due to repeated sorting)
  • Optimal approach (heaps): O(log n) per insertion

C++ Solution (OOP + Simple Approach)

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;

 

class Statistics {

private:

    vector<int> data;

 

public:

    void addNumber(int x) {

        data.push_back(x);

    }

 

    double getMedian() {

        vector<int> temp = data;

        sort(temp.begin(), temp.end());

 

        int n = temp.size();

 

        if (n % 2 == 1) {

            return temp[n / 2];

        } else {

            return (temp[n / 2 - 1] + temp[n / 2]) / 2.0;

        }

    }

};

 

int main() {

    Statistics stats;

    int x;

 

    while (cin >> x) {

        stats.addNumber(x);

        cout << stats.getMedian() << endl;

    }

 

    return 0;

}


Explanation

Step 1: Read input continuously

while (cin >> x)

Stops only at EOF.


Step 2: Store numbers

data.push_back(x);

We keep all numbers in a vector.


Step 3: Sort and compute median

sort(temp.begin(), temp.end());

Then:

  • Odd count → middle element
  • Even count → average of middle two

Example

Input

1

3

4

2

Step-by-step

Numbers

Sorted

Median

1

[1]

1

1,3

[1,3]

2

1,3,4

[1,3,4]

3

1,3,4,2

[1,2,3,4]

2.5


Output

1

2

3

2.5


OOP Concepts Used

  • Class: Statistics
  • Private data member: data
  • Member functions:
    • addNumber()
    • getMedian()
  • Encapsulation of dataset and logic

Common Mistakes

  • Forgetting to sort before computing median
  • Using integer division instead of floating point
  • Not handling even-sized cases correctly
  • Assuming fixed input size (problem uses EOF)

Final Rule

Median = middle element (odd) OR average of two middle elements (even)


Conclusion

This problem introduces an important statistical concept in programming:

  • Median calculation
  • Stream processing
  • Sorting-based solutions
  • Object-oriented design in C++

 

These are excellent beginner problems:

 

  • 100 The 3n + 1 Problem
  • 272 TEX Quotes
  • 10038 Jolly Jumpers
  • 10107 What is the Median?

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Problem Statement

For any positive integer n, define the following process:

  • If n is even, divide it by 2 → n = n / 2
  • If n is odd, multiply by 3 and add 1 → n = 3n + 1

Repeat this process until n becomes 1.

The cycle length of a number is the number of terms in the sequence starting from n and ending at 1.


Task

Given two integers i and j, compute:

  • The maximum cycle length for all numbers between i and j (inclusive)

Input Format

Each line contains two integers:

i j

Input ends at EOF.


Output Format

For each pair (i, j), print:

i j max_cycle_length


Important Note

If i > j, swap them before processing.


Key Idea

We compute the cycle length for every number in the range and take the maximum.

To optimize:

  • Use memoization (caching) to store previously computed cycle lengths.

Algorithm

  1. Read i and j
  2. Swap if needed
  3. For each number from i to j:
    • Compute cycle length using Collatz rules
    • Track maximum
  4. Print result

Time Complexity

  • Naive: O(n × cycle_length)
  • Optimized with memoization: significantly faster in practice

C++ Solution (OOP + Memoization)

#include <iostream>

#include <unordered_map>

using namespace std;

 

class Collatz {

private:

    unordered_map<long long, int> memo;

 

public:

    int cycleLength(long long n) {

        if (n == 1) return 1;

 

        if (memo.count(n))

            return memo[n];

 

        long long next;

        if (n % 2 == 0)

            next = n / 2;

        else

            next = 3 * n + 1;

 

        memo[n] = 1 + cycleLength(next);

        return memo[n];

    }

 

    int maxCycle(int i, int j) {

        if (i > j) swap(i, j);

 

        int maxLen = 0;

 

        for (int k = i; k <= j; k++) {

            int len = cycleLength(k);

            if (len > maxLen)

                maxLen = len;

        }

 

        return maxLen;

    }

};

 

int main() {

    Collatz solver;

 

    long long i, j;

 

    while (cin >> i >> j) {

        cout << i << " " << j << " " << solver.maxCycle(i, j) << endl;

    }

 

    return 0;

}


Explanation

Step 1: Read input

while (cin >> i >> j)

Handles multiple test cases until EOF.


Step 2: Ensure correct order

if (i > j) swap(i, j);


Step 3: Compute cycle length

Rules:

n → n/2 (if even)

n → 3n+1 (if odd)


Step 4: Memoization

memo[n] = 1 + cycleLength(next);

Stores results to avoid recomputation.


Step 5: Find maximum

for (int k = i; k <= j; k++)

Track maximum cycle length.


Example

Input

1 10

Cycle lengths (sample)

n

Cycle Length

1

1

2

2

3

8

7

17

Output

1 10 20


OOP Concepts Used

  • Class: Collatz
  • Private data member: memo
  • Member functions:
    • cycleLength()
    • maxCycle()
  • Encapsulation of algorithm logic
  • Memoization inside object

Common Mistakes

  • Not swapping i and j
  • Overflow for large n (use long long)
  • Not using memoization (TLE risk)
  • Incorrect cycle counting

Final Rule

Compute Collatz cycle length for all numbers in range and take maximum


Conclusion

This problem is a classic ICPC-style problem that teaches:

  • Recursion
  • Memoization (dynamic programming idea)
  • Range processing
  • Optimization techniques
  • Object-oriented design in C++

 

 

 

Problem Statement

In plain text, quotation marks are written as:

"

But in TEX typesetting, quotes must be replaced with:

  • Opening quote → `` (two backticks)
  • Closing quote → '' (two single quotes)

Your task is to convert all straight double quotes in the input into TEX-style quotes, preserving all other characters.


Input Format

  • Input consists of multiple lines of text.
  • Each " character must be replaced accordingly.

Output Format

Print the modified text with TEX-style quotes.


Key Idea

We alternate between:

  • Opening quote → `` (two backticks)
  • Closing quote → '' (two apostrophes)

We track whether we are inside a quoted section or not.


Algorithm

  1. Initialize a boolean flag open = true
  2. Read input character by character
  3. If character is ":
    • If open is true → print ```` (two backticks)
    • Else → print ''
    • Toggle open
  4. Otherwise, print the character as it is

Time Complexity

O(n) where n is number of characters.


C++ Solution (OOP Style)

#include <iostream>

using namespace std;

 

class TEXQuotes {

private:

    bool openQuote;

 

public:

    // Constructor

    TEXQuotes() {

        openQuote = true;

    }

 

    void process() {

        char c;

 

        while (cin.get(c)) {

            if (c == '"') {

                if (openQuote) {

                    cout << "``";

                } else {

                    cout << "''";

                }

                openQuote = !openQuote;

            } else {

                cout << c;

            }

        }

    }

};

 

int main() {

    TEXQuotes converter;

    converter.process();

 

    return 0;

}


Explanation

Step 1: Read character-by-character input

cin.get(c);

This ensures we preserve spaces and newlines.


Step 2: Track quote state

bool openQuote;

  • true → next quote is opening
  • false → next quote is closing

Step 3: Replace quotes

Input

Output

"

`` (opening)

"

'' (closing)


Example

Input

"To be or not to be," she said.

Output

``To be or not to be,'' she said.


OOP Concepts Used

  • Class: TEXQuotes
  • Private data member: openQuote
  • Constructor: initializes state
  • Member function: process()
  • Encapsulation of streaming logic

Common Mistakes

  • Using string input instead of character stream
  • Not toggling quote state
  • Replacing quotes globally without order tracking
  • Forgetting spaces/newlines preservation

Final Rule

First " → `` 

Second " → '' 

Repeat alternately


Conclusion

This problem is an important string-streaming problem that teaches:

  • Character-by-character input handling
  • State management (finite state machine idea)
  • Stream processing
  • Object-oriented design in C++

 

 

 

 

 

 

 

 

 

 

 

Problem Statement

A sequence of n integers is called a Jolly Jumper if the set of absolute differences between successive elements contains all integers from:

1 to n-1

Each difference must appear exactly once, regardless of order.


Example

Input

4 1 4 2 3

Differences

|1-4| = 3

|4-2| = 2

|2-3| = 1

We get: {1, 2, 3} → valid → Jolly


Input Format

Each line contains:

  • An integer n
  • Followed by n integers

Input ends at EOF.


Output Format

For each sequence, print:

  • Jolly if it is a Jolly Jumper
  • Not jolly otherwise

Key Idea

We check:

  1. Compute absolute differences between consecutive elements
  2. Mark which differences appear
  3. Ensure all values from 1 to n-1 exist

Algorithm

  1. Read n
  2. Read array of size n
  3. Create boolean array seen[n]
  4. For each i from 0 to n-2:
    • compute diff = abs(a[i] - a[i+1])
    • if diff in range [1, n-1], mark it
  5. Check if all values from 1 to n-1 are marked

Time Complexity

O(n) per test case


C++ Solution (OOP Style)

#include <iostream>

#include <cmath>

using namespace std;

 

class JollyChecker {

private:

    int arr[3000];

    bool seen[3000];

    int n;

 

public:

    JollyChecker(int size) {

        n = size;

    }

 

    void readInput() {

        for (int i = 0; i < n; i++) {

            cin >> arr[i];

        }

    }

 

    string check() {

        for (int i = 0; i < n; i++)

            seen[i] = false;

 

        for (int i = 0; i < n - 1; i++) {

            int diff = abs(arr[i] - arr[i + 1]);

 

            if (diff >= 1 && diff <= n - 1)

                seen[diff] = true;

        }

 

        for (int i = 1; i <= n - 1; i++) {

            if (!seen[i])

                return "Not jolly";

        }

 

        return "Jolly";

    }

};

 

int main() {

    int n;

 

    while (cin >> n) {

        JollyChecker obj(n);

        obj.readInput();

 

        cout << obj.check() << endl;

    }

 

    return 0;

}


Explanation

Step 1: Read sequence

cin >> n;


Step 2: Compute differences

diff = abs(arr[i] - arr[i+1]);


Step 3: Track differences

seen[diff] = true;

We mark which differences appear.


Step 4: Validate condition

We must have:

all values from 1 to n-1 must exist


Example Walkthrough

Input

5 1 4 2 3 5

Differences

|1-4| = 3

|4-2| = 2

|2-3| = 1

|3-5| = 2

Set = {1,2,3} → valid → Jolly


OOP Concepts Used

  • Class: JollyChecker
  • Private data: arr, seen, n
  • Constructor: initializes size
  • Member functions:
    • readInput()
    • check()
  • Encapsulation of validation logic

Common Mistakes

  • Forgetting absolute value
  • Not checking full range 1 to n-1
  • Indexing errors in seen[]
  • Not resetting array for each test case

Final Rule

A sequence is Jolly if all differences 1..n-1 appear exactly once


Conclusion

This problem is a classic beginner-to-intermediate problem that teaches:

  • Array processing
  • Absolute differences
  • Boolean marking techniques
  • Input until EOF
  • Object-oriented programming in C++

 

 

 

 

 

 

 

Problem Statement

You are given a stream of integers. After each new integer is read, you must output the median of all numbers seen so far.

  • If the number of elements is odd → median is the middle value.
  • If the number of elements is even → median is the average of the two middle values.

You must print the median after every input number.


Input Format

A sequence of integers, one per line.

  • Input continues until EOF.

Output Format

After reading each number, print the current median.


Key Idea

We maintain a dynamic median as numbers arrive.

Efficient approach (ICPC standard):

  • Max-heap → lower half
  • Min-heap → upper half

This keeps middle elements accessible in O(log n).


Algorithm (Optimal)

  1. Maintain two heaps:
    • maxHeap (lower half)
    • minHeap (upper half)
  2. For each number:
    • Insert into appropriate heap
    • Balance heaps (size difference ≤ 1)
  3. Compute median:
    • If equal size → average of roots
    • Else → root of larger heap

Time Complexity

  • Each insertion: O(log n)
  • Each median query: O(1)

C++ Solution (OOP + Heap Based)

#include <iostream>

#include <queue>

using namespace std;

 

class MedianStream {

private:

    priority_queue<int> maxHeap;

    priority_queue<int, vector<int>, greater<int>> minHeap;

 

public:

    void addNumber(int x) {

        if (maxHeap.empty() || x <= maxHeap.top())

            maxHeap.push(x);

        else

            minHeap.push(x);

 

        // Balance heaps

        if (maxHeap.size() > minHeap.size() + 1) {

            minHeap.push(maxHeap.top());

            maxHeap.pop();

        }

        else if (minHeap.size() > maxHeap.size()) {

            maxHeap.push(minHeap.top());

            minHeap.pop();

        }

    }

 

    double getMedian() {

        if (maxHeap.size() > minHeap.size())

            return maxHeap.top();

 

        return (maxHeap.top() + minHeap.top()) / 2.0;

    }

};

 

int main() {

    MedianStream ms;

    int x;

 

    while (cin >> x) {

        ms.addNumber(x);

        cout << ms.getMedian() << endl;

    }

 

    return 0;

}


Explanation

Step 1: Maintain two heaps

priority_queue<int> maxHeap;

priority_queue<int, vector<int>, greater<int>> minHeap;

  • maxHeap → smaller half
  • minHeap → larger half

Step 2: Insert number

if (x <= maxHeap.top())

Decides which side the number belongs to.


Step 3: Balance heaps

Ensure:

|size(maxHeap) - size(minHeap)| ≤ 1


Step 4: Compute median

  • Odd count → top of maxHeap
  • Even count → average of two heap tops

Example

Input

1

3

4

2

Processing

Numbers

Median

1

1

1,3

2

1,3,4

3

1,3,4,2

2.5


Output

1

2

3

2.5


OOP Concepts Used

  • Class: MedianStream
  • Private data:
    • maxHeap
    • minHeap
  • Member functions:
    • addNumber()
    • getMedian()
  • Encapsulation of streaming logic

Common Mistakes

  • Using only sorting (too slow)
  • Forgetting heap balancing
  • Integer division instead of floating-point
  • Not handling EOF input correctly

Final Rule

Maintain two heaps and balance them to compute median dynamically


Conclusion

This problem is a classic streaming statistics problem that teaches:

  • Heaps (priority queues)
  • Dynamic data structures
  • Median maintenance
  • Efficient algorithm design
  • Object-oriented programming in C++

It is a key ICPC-level concept often used in real contest problems.

 

 

 

 

 

 

Problem Statement

You are given an integer n. You must repeatedly apply the following rules until n becomes 1:

  • If n is even, divide it by 2 → n = n / 2
  • If n is odd, multiply it by 3 and add 1 → n = 3n + 1

Print all values of n in the sequence, starting from the initial value.


Input Format

  • A single integer n

Output Format

Print the full sequence of numbers, starting from n and ending at 1, separated by spaces.


Key Idea

This is the classic Collatz sequence. We repeatedly apply a deterministic rule until reaching 1.


Algorithm

  1. Read n
  2. While n != 1:
    • Print n
    • If n is even → n /= 2
    • Else → n = 3n + 1
  3. Print 1

Time Complexity

  • Not strictly bounded mathematically, but works efficiently for constraints in CSES Problem Set
  • Typical complexity: proportional to sequence length

C++ Solution (OOP Style)

#include <iostream>

using namespace std;

 

class WeirdAlgorithm {

private:

    long long n;

 

public:

    WeirdAlgorithm(long long value) {

        n = value;

    }

 

    void generate() {

        while (n != 1) {

            cout << n << " ";

 

            if (n % 2 == 0)

                n = n / 2;

            else

                n = 3 * n + 1;

        }

 

        cout << 1 << endl;

    }

};

 

int main() {

    long long n;

    cin >> n;

 

    WeirdAlgorithm obj(n);

    obj.generate();

 

    return 0;

}


Explanation

Step 1: Start from n

n = starting value


Step 2: Apply rules

  • Even → divide by 2
  • Odd → multiply by 3 and add 1

Step 3: Stop condition

Stop when n == 1


Example

Input

3

Process

3 → 10 → 5 → 16 → 8 → 4 → 2 → 1

Output

3 10 5 16 8 4 2 1


OOP Concepts Used

  • Class: WeirdAlgorithm
  • Private data member: n
  • Constructor: initializes starting value
  • Member function: generate()
  • Encapsulation of sequence logic

Common Mistakes

  • Forgetting to print the last value 1
  • Using int instead of long long (overflow risk)
  • Incorrect loop termination condition
  • Printing extra spaces incorrectly

Final Rule

If n is even → n = n / 2 

If n is odd  → n = 3n + 1 

Repeat until n = 1


Conclusion

This problem is a foundational exercise in:

  • Basic simulation
  • Conditional logic
  • Looping
  • Sequence generation
  • Object-oriented programming in C++

It is often one of the first problems recommended for beginners entering competitive programming.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Problem Statement

You are given all integers from 1 to n, but one number is missing.

You are given n − 1 distinct numbers. Your task is to find the missing number.


Input Format

  • First line: integer n
  • Second line: n − 1 integers, all distinct, in range 1 to n

Output Format

Print the missing number.


Key Idea

Instead of checking each number, we use a mathematical observation:

Method 1: Sum Formula

Sum of first n natural numbers:

total = n(n + 1) / 2

Missing number:

missing = total - sum_of_given_numbers


Method 2: XOR Trick (Alternative)

  • a ^ a = 0
  • a ^ 0 = a

XOR all numbers from 1 to n and XOR all input numbers → result is missing number.


Algorithm (Sum Method)

  1. Read n
  2. Compute expected sum = n * (n + 1) / 2
  3. Read all n - 1 numbers and compute actual sum
  4. Return difference

Time Complexity

  • O(n)

Space Complexity

  • O(1) (if streaming input)

C++ Solution (OOP Style)

#include <iostream>

using namespace std;

 

class MissingNumber {

private:

    long long n;

    long long sumGiven;

 

public:

    MissingNumber(long long size) {

        n = size;

        sumGiven = 0;

    }

 

    void readAndCompute() {

        long long x;

        for (long long i = 0; i < n - 1; i++) {

            cin >> x;

            sumGiven += x;

        }

    }

 

    long long findMissing() {

        long long total = n * (n + 1) / 2;

        return total - sumGiven;

    }

};

 

int main() {

    long long n;

    cin >> n;

 

    MissingNumber solver(n);

    solver.readAndCompute();

 

    cout << solver.findMissing() << endl;

 

    return 0;

}


Explanation

Step 1: Compute expected total

1 + 2 + ... + n


Step 2: Compute given sum

We add all input numbers.


Step 3: Subtract

missing = total - given_sum


Example

Input

5

2 3 1 5

Calculation

  • Total = 15
  • Given = 11

Output

4


OOP Concepts Used

  • Class: MissingNumber
  • Private data members: n, sumGiven
  • Constructor: initializes state
  • Member functions:
    • readAndCompute()
    • findMissing()
  • Encapsulation of logic

Common Mistakes

  • Using int instead of long long
  • Forgetting one number in sum
  • Overflow in n(n+1)/2
  • Misreading input size (n-1 numbers)

Final Rule

Missing = (1 to n sum) − (given numbers sum)


Conclusion

This problem is a classic introduction to:

  • Mathematical reasoning
  • Summation formulas
  • Efficient input handling
  • Basic problem decomposition
  • Object-oriented programming in C++

It is one of the most important starter problems in competitive programming.

 

 

 

 

 

 

 

Problem Statement

You are given a DNA string consisting of characters:

A, C, G, T

Your task is to find the length of the longest substring where the same character appears consecutively.


Input Format

  • A single string s

Output Format

Print one integer — the maximum length of a contiguous repeating substring.


Key Idea

We scan the string and count consecutive equal characters.

Whenever the character changes, we reset the counter.

We maintain a global maximum.


Algorithm

  1. Read string s
  2. Initialize:
    • current = 1
    • best = 1
  3. Loop from index 1 to end:
    • If s[i] == s[i-1] → increment current
    • Else → reset current = 1
    • Update best = max(best, current)
  4. Print best

Time Complexity

  • O(n) where n is length of string

C++ Solution (OOP Style)

#include <iostream>

#include <string>

using namespace std;

 

class Repetitions {

private:

    string s;

 

public:

    Repetitions(string str) {

        s = str;

    }

 

    int longestRun() {

        int best = 1;

        int current = 1;

 

        for (int i = 1; i < s.length(); i++) {

            if (s[i] == s[i - 1])

                current++;

            else

                current = 1;

 

            if (current > best)

                best = current;

        }

 

        return best;

    }

};

 

int main() {

    string s;

    cin >> s;

 

    Repetitions obj(s);

 

    cout << obj.longestRun() << endl;

 

    return 0;

}


Explanation

Step 1: Read string

AGAAAACCC


Step 2: Track consecutive characters

Example:

A G A A A A C C C

Runs:

  • A → 1
  • G → 1
  • A → 4
  • C → 3

Step 3: Keep maximum

Final answer:

4


Example

Input

ATTCGGGA

Output

3

Explanation:

  • TT → 2
  • GGG → 3 (maximum)

OOP Concepts Used

  • Class: Repetitions
  • Private data member: s
  • Constructor: initializes string
  • Member function: longestRun()
  • Encapsulation of scanning logic

Common Mistakes

  • Forgetting to initialize best = 1
  • Not resetting current when character changes
  • Starting loop from index 0 instead of 1

Final Rule

Track consecutive equal characters and maintain maximum length


Conclusion

This problem is a fundamental string processing problem that teaches:

  • String traversal
  • Two-pointer-like scanning logic
  • State tracking
  • Simple dynamic counting
  • Object-oriented programming in C++

It is one of the easiest but most important introductory string problems in competitive programming.

 

 

 

 

 

 

Problem Statement

You are given an array of n integers. Your task is to make the array non-decreasing:

a1 ≤ a2 ≤ a3 ≤ ... ≤ an

You can increase any element any number of times.

Find the minimum total number of increments needed.


Input Format

  • First line: integer n
  • Second line: n integers

Output Format

Print one integer — the minimum number of increments required.


Key Idea

We traverse the array from left to right.

Whenever we find:

a[i] < a[i - 1]

We increase a[i] to match a[i - 1].

We accumulate the total increments.


Algorithm

  1. Read n
  2. Read array a
  3. Initialize moves = 0
  4. For each i from 1 to n-1:
    • If a[i] < a[i-1]:
      • moves += (a[i-1] - a[i])
      • set a[i] = a[i-1]
  5. Print moves

Time Complexity

  • O(n)

C++ Solution (OOP Style)

#include <iostream>

using namespace std;

 

class IncreasingArray {

private:

    long long arr[200000];

    int n;

 

public:

    IncreasingArray(int size) {

        n = size;

    }

 

    void readInput() {

        for (int i = 0; i < n; i++) {

            cin >> arr[i];

        }

    }

 

    long long makeIncreasing() {

        long long moves = 0;

 

        for (int i = 1; i < n; i++) {

            if (arr[i] < arr[i - 1]) {

                moves += (arr[i - 1] - arr[i]);

                arr[i] = arr[i - 1];

            }

        }

 

        return moves;

    }

};

 

int main() {

    int n;

    cin >> n;

 

    IncreasingArray obj(n);

    obj.readInput();

 

    cout << obj.makeIncreasing() << endl;

 

    return 0;

}


Explanation

Step 1: Read array

Example:

3 2 5 1 7


Step 2: Fix violations

We ensure each element is at least as large as the previous one.


Step 3: Count increments

Step

Array

Moves

start

3 2 5 1 7

0

fix 2

3 3 5 1 7

1

fix 1

3 3 5 5 7

4


Example

Input

5

3 2 5 1 7

Output

4


OOP Concepts Used

  • Class: IncreasingArray
  • Private data member: arr, n
  • Constructor: initializes size
  • Member functions:
    • readInput()
    • makeIncreasing()
  • Encapsulation of logic

Common Mistakes

  • Not updating array after increment
  • Using wrong condition (> instead of <)
  • Using int instead of long long for moves
  • Missing left-to-right traversal requirement

Final Rule

If a[i] < a[i-1], increase a[i] to a[i-1] and count the difference


Conclusion

This problem is a key greedy problem that teaches:

  • Array traversal
  • Greedy adjustment
  • Prefix dependency handling
  • Accumulation techniques
  • Object-oriented programming in C++

It is an essential stepping stone for ICPC-level greedy problems.

 

 

 

Problem Statement

You are given an integer n. You must construct a permutation of numbers from 1 to n such that:

  • No two adjacent numbers differ by 1.

If such a permutation exists, print it. Otherwise, print:

NO SOLUTION


Input Format

  • A single integer n

Output Format

  • A valid permutation of 1..n, or
  • NO SOLUTION if impossible

Key Idea

We must avoid placing consecutive integers next to each other.

Observation:

  • For n = 1, valid: [1]
  • For n = 2, 3, impossible
  • For n ≥ 4, we can construct a solution by:

Strategy:

Print all even numbers first, then all odd numbers.

This avoids adjacent differences of 1.


Algorithm

  1. If n == 1, print 1
  2. If n == 2 or n == 3, print NO SOLUTION
  3. Otherwise:
    • Print all even numbers from 1..n
    • Then print all odd numbers from 1..n

Time Complexity

  • O(n)

C++ Solution (OOP Style)

#include <iostream>

using namespace std;

 

class Permutations {

private:

    int n;

 

public:

    Permutations(int size) {

        n = size;

    }

 

    void generate() {

        if (n == 1) {

            cout << 1 << endl;

            return;

        }

 

        if (n == 2 || n == 3) {

            cout << "NO SOLUTION" << endl;

            return;

        }

 

        // Print even numbers

        for (int i = 2; i <= n; i += 2)

            cout << i << " ";

 

        // Print odd numbers

        for (int i = 1; i <= n; i += 2)

            cout << i << " ";

 

        cout << endl;

    }

};

 

int main() {

    int n;

    cin >> n;

 

    Permutations obj(n);

    obj.generate();

 

    return 0;

}


Explanation

Step 1: Handle small cases

n = 2 → impossible

n = 3 → impossible

Because any arrangement will have adjacent numbers differing by 1.


Step 2: Construct valid pattern

Example for n = 6:

Even numbers:

2 4 6

Odd numbers:

1 3 5

Final output:

2 4 6 1 3 5


Example

Input

5

Output

2 4 1 3 5


OOP Concepts Used

  • Class: Permutations
  • Private data member: n
  • Constructor: initializes value
  • Member function: generate()
  • Encapsulation of construction logic

Common Mistakes

  • Forgetting special cases (n = 2, 3)
  • Mixing order incorrectly
  • Not spacing output properly
  • Trying random permutations instead of constructive approach

Final Rule

Place all even numbers first, then all odd numbers


Conclusion

This problem is a classic constructive algorithm problem that teaches:

  • Pattern construction
  • Edge case handling
  • Modular thinking
  • Greedy construction
  • Object-oriented design in C++

It is an important step toward learning constructive problems in ICPC preparation.

 

 

 

 

 

 

Problem Statement

You are given a grid where numbers are arranged in a spiral pattern starting from (1,1):

1   2   9   10

4   3   8   11

5   6   7   12

16  15  14  13

For each query (y, x), you must find the number located at that position.


Input Format

  • First line: integer t (number of queries)
  • Next t lines: two integers y x

Output Format

For each query, print the number at position (y, x).


Key Idea

Instead of building the grid, we use a mathematical pattern.

The value depends on the maximum of (x, y):

Let:

n = max(x, y)

We determine the spiral layer and compute based on whether the layer is even or odd.


Pattern Observation

If n is odd:

  • Numbers increase downward and leftward in that layer

If n is even:

  • Numbers increase upward and rightward

We compute the base value:

n² - (something)


Formula

If n = max(x, y):

Case 1: n is even

  • If x == n:

value = n² - y + 1

  • Else:

value = (n-1)² + x


Case 2: n is odd

  • If y == n:

value = n² - x + 1

  • Else:

value = (n-1)² + y


Algorithm

  1. Read number of queries t
  2. For each (y, x):
    • Compute n = max(x, y)
    • Apply correct formula based on parity of n
  3. Print result

Time Complexity

  • O(t)

Each query is solved in constant time.


C++ Solution (OOP Style)

#include <iostream>

using namespace std;

 

class NumberSpiral {

public:

    long long getValue(long long y, long long x) {

        long long n = max(x, y);

        long long ans;

 

        if (n % 2 == 0) {

            if (x == n)

                ans = n * n - y + 1;

            else

                ans = (n - 1) * (n - 1) + x;

        } else {

            if (y == n)

                ans = n * n - x + 1;

            else

                ans = (n - 1) * (n - 1) + y;

        }

 

        return ans;

    }

};

 

int main() {

    ios::sync_with_stdio(false);

    cin.tie(nullptr);

 

    int t;

    cin >> t;

 

    NumberSpiral solver;

 

    while (t--) {

        long long y, x;

        cin >> y >> x;

        cout << solver.getValue(y, x) << "\n";

    }

 

    return 0;

}


Explanation

Step 1: Identify layer

n = max(x, y)

Each square layer ends at n².


Step 2: Determine direction

  • Even layer → pattern goes one way
  • Odd layer → pattern goes opposite way

Step 3: Compute value in O(1)

No grid construction needed.


Example

Input

3

1 1

2 3

4 2

Output

1

8

15


OOP Concepts Used

  • Class: NumberSpiral
  • Method: getValue()
  • Encapsulation of formula logic
  • Stateless design (efficient reuse)

Common Mistakes

  • Confusing (x, y) order
  • Using wrong square (n²) base
  • Not handling parity correctly
  • Overflow (use long long)

Final Rule

Answer depends on max(x,y) layer and whether it is even or odd


Conclusion

This problem is a classic mathematical pattern problem that teaches:

  • Grid observation
  • Mathematical derivation
  • Constant-time query solving
  • Pattern recognition
  • Object-oriented implementation in C++

It is a key problem for developing ICPC-level problem-solving intuition.

 

 

 

 

 

 

 

 

 

 

 

Problem Statement

You are given an n × n chessboard. You must determine, for each size k × k (from 1 to n), how many ways you can place two knights such that they do not attack each other.


Key Idea

Two knights attack each other only if they are placed in an L-shape (2 by 1 moves).

Total ways to place two knights:

C(k², 2) = k²(k² - 1) / 2

From this, subtract attacking pairs.


Attacking Positions

A knight attacks in 2 specific relative configurations:

  • 2 × 1 blocks
  • Each 2×3 or 3×2 rectangle contributes attacking pairs

Number of attacking pairs:

4 × (k - 1) × (k - 2)


Final Formula

For board size k:

answer = k²(k² - 1) / 2 - 4(k - 1)(k - 2)


Algorithm

  1. Read n
  2. For each k from 1 to n:
    • Compute total placements
    • Subtract attacking positions
  3. Print result

Time Complexity

  • O(n)

C++ Solution (OOP Style)

#include <iostream>

using namespace std;

 

class TwoKnights {

public:

    long long countWays(long long k) {

        long long total = (k * k) * (k * k - 1) / 2;

 

        long long attack = 0;

        if (k > 2)

            attack = 4 * (k - 1) * (k - 2);

 

        return total - attack;

    }

};

 

int main() {

    long long n;

    cin >> n;

 

    TwoKnights solver;

 

    for (long long k = 1; k <= n; k++) {

        cout << solver.countWays(k) << "\n";

    }

 

    return 0;

}


Explanation

Step 1: Total placements

Choose any 2 squares:

k² choose 2


Step 2: Remove attacking pairs

Each 2×3 or 3×2 region contains 2 attacking pairs per orientation → total:

4(k - 1)(k - 2)


Step 3: Edge cases

  • For k = 1 → 0
  • For k = 2 → 6 (no attacks possible)

Example

Input

5

Output

0

6

28

96

252


OOP Concepts Used

  • Class: TwoKnights
  • Method: countWays()
  • Encapsulation of combinatorics logic
  • Stateless reusable design

Common Mistakes

  • Forgetting k > 2 condition
  • Overflow (use long long)
  • Miscounting attacking configurations
  • Incorrect combinatorics formula

Final Rule

Answer = total ways to choose 2 squares − attacking knight pairs


Conclusion

This problem is an important combinatorics problem that teaches:

  • Counting techniques
  • Grid-based reasoning
  • Subtraction principle
  • Pattern recognition
  • Object-oriented implementation in C++

It is a classic ICPC preparation problem for combinatorics fundamentals.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Problem Statement

You are given an integer n. Your task is to split the set:

{1, 2, 3, ..., n}

into two subsets such that:

  • Both subsets have equal sum, or
  • If it is impossible, print NO

If possible, print:

  • YES
  • Then the elements of each subset

Key Idea

Let total sum be:

S = n(n + 1) / 2

For two equal subsets, we need:

S must be even

If S is odd → impossible.


Construction Strategy

We greedily assign numbers from n → 1 into two sets:

  • Put a number in set A if it does not exceed remaining sum
  • Otherwise put it in set B

We aim to make both sums equal to S/2.


Algorithm

  1. Compute total sum S
  2. If S % 2 != 0 → print NO
  3. Target = S / 2
  4. Start from n down to 1:
    • If i <= target, put in set A and reduce target
    • Else put in set B
  5. Print both sets

Time Complexity

  • O(n)

C++ Solution (OOP Style)

#include <iostream>

#include <vector>

using namespace std;

 

class TwoSets {

private:

    vector<int> set1, set2;

 

public:

    void solve(int n) {

        long long total = (long long)n * (n + 1) / 2;

 

        if (total % 2 != 0) {

            cout << "NO\n";

            return;

        }

 

        cout << "YES\n";

 

        long long target = total / 2;

 

        for (int i = n; i >= 1; i--) {

            if (i <= target) {

                set1.push_back(i);

                target -= i;

            } else {

                set2.push_back(i);

            }

        }

 

        cout << set1.size() << "\n";

        for (int x : set1) cout << x << " ";

        cout << "\n";

 

        cout << set2.size() << "\n";

        for (int x : set2) cout << x << " ";

        cout << "\n";

    }

};

 

int main() {

    int n;

    cin >> n;

 

    TwoSets solver;

    solver.solve(n);

 

    return 0;

}


Explanation

Step 1: Check feasibility

If total sum is odd:

NO solution exists


Step 2: Greedy assignment

We try to build one subset with sum = S/2.


Step 3: Fill second subset automatically

Remaining numbers go to second set.


Example

Input

7

Total sum

28 → each set must sum to 14

Output (one valid solution)

YES

3

7 6 1

4

5 4 3 2


OOP Concepts Used

  • Class: TwoSets
  • Private data members: set1, set2
  • Member function: solve()
  • Encapsulation of greedy construction logic

Common Mistakes

  • Forgetting to check sum parity
  • Not resetting target correctly
  • Printing incorrect format
  • Using inefficient subset generation

Final Rule

Split {1..n} into two equal-sum subsets if total sum is even


Conclusion

This problem is a classic greedy + construction problem that teaches:

  • Mathematical feasibility checking
  • Greedy subset construction
  • Partitioning techniques
  • Output formatting
  • Object-oriented design in C++

It is a fundamental ICPC-style constructive algorithm problem.

 

Skills covered

By solving these 25 problems, students will become comfortable with:

  • Time complexity analysis
  • Arrays and strings
  • Basic mathematics
  • Number theory
  • Sorting and searching
  • Prefix sums
  • Two pointers
  • Stack and queue
  • Graph traversal (BFS)
  • Recursion and backtracking
  • Dynamic programming basics

This foundation is sufficient for students to start solving ICPC regional-level Div. 2/A–C style problems before progressing to more advanced topics such as segment trees, union-find, shortest paths, and advanced dynamic programming.

 

 

কোন মন্তব্য নেই:

একটি মন্তব্য পোস্ট করুন