Competitive Programming Problem Solutions: Basic Algorithms and Data Structures

Problem 1: Character Output

Output each character of the string "I Love GPLT" on a separate line.

#include <iostream>
using namespace std;

int main() {
    string msg = "I Love GPLT";
    for (char c : msg) {
        cout << c << '\n';
    }
    return 0;
}

Problem 2: Standard Weight Calculation

Given a person's height, calculate their standard weight using the formula: (height - 100) × 0.9 × 2, rounded to one decimal place.

#include <cstdio>
using namespace std;

int main() {
    int height;
    scanf("%d", &height);
    double weight = (height - 100) * 1.8;
    printf("%.1lf\n", weight);
    return 0;
}

Problem 3: Bell Tower

Simulate a bell tower that rings based on the current time. If the time is before 12:00, output the current time. Otherwise, ring the bell for each hour past noon.

#include <cstdio>
using namespace std;

int main() {
    int hour, minute;
    scanf("%d:%d", &hour, &minute);
    
    int totalMinutes = hour * 60 + minute;
    
    if (totalMinutes < 12 * 60) {
        printf("Only %02d:%02d.  Too early to Dang.", hour, minute);
    } else {
        int rings = (totalMinutes + 59) / 60 - 12;
        for (int i = 0; i < rings; i++) {
            printf("Dang");
        }
    }
    return 0;
}

Problem 4: Weight Judgment

Determine if a person's weight is within 10% of their standard weight, overweight, or underweight.

#include <cstdio>
#include <cmath>
using namespace std;

int main() {
    int testCases;
    scanf("%d", &testCases);
    
    while (testCases--) {
        double height, weight;
        scanf("%lf %lf", &height, &weight);
        
        double standard = (height - 100) * 1.8;
        double tolerance = standard * 0.1;
        double difference = fabs(weight - standard);
        
        if (difference < tolerance) {
            printf("You are wan mei!\n");
        } else if (weight > standard) {
            printf("You are tai pang le!\n");
        } else {
            printf("You are tai shou le!\n");
        }
    }
    return 0;
}

Problem 5: Valentine's Day

Process a list of names and determine the output based on position: 2nd person is special, 14th person gets invited together with the 2nd.

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<string> names;
    string input;
    
    while (cin >> input && input != ".") {
        names.push_back(input);
    }
    
    if (names.size() < 2) {
        cout << "Momo... No one is for you ...\n";
    } else if (names.size() < 14) {
        cout << names[1] << " is the only one for you...\n";
    } else {
        cout << names[1] << " and " << names[13] << " are inviting you to dinner...\n";
    }
    return 0;
}
</string>

Problem 6: Alien Day

Convert Earth time to alien time format. Aliens use a different time system where their day has different duration.

#include <cstdio>
using namespace std;

int main() {
    int queries;
    scanf("%d", &queries);
    
    while (queries--) {
        int day, hour, minute;
        scanf("%d %d:%d", &day, &hour, &minute);
        
        if (day == 0) {
            printf("%d %02d:%02d\n", day, hour, minute);
        } else {
            int totalMin = hour * 60 + minute;
            if (day % 2 == 0) {
                totalMin += 24 * 60;
            }
            int newDay = (day + 1) / 2;
            int newHour = totalMin / 120;
            int newMin = (totalMin / 2) % 60;
            printf("%d %02d:%02d\n", newDay, newHour, newMin);
        }
    }
    return 0;
}

Problem 7: Universal Addition

Perform addition with variable base systems. Each digit position has its own base defined by the input.

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

int main() {
    string base, num1, num2;
    cin >> base >> num1 >> num2;
    
    // Pad strings to equal length
    int maxLen = max({base.length(), num1.length(), num2.length()});
    while (base.length() < maxLen) base = '0' + base;
    while (num1.length() < maxLen) num1 = '0' + num1;
    while (num2.length() < maxLen) num2 = '0' + num2;
    
    string result(maxLen + 1, '0');
    int carry = 0;
    
    for (int i = maxLen - 1; i >= 0; i--) {
        int b = base[i] - '0';
        if (b == 0) b = 10;
        
        int sum = (num1[i] - '0') + (num2[i] - '0') + carry;
        carry = sum / b;
        result[i + 1] = '0' + (sum % b);
    }
    result[0] = '0' + carry;
    
    // Remove leading zeros
    size_t pos = result.find_first_not_of('0');
    if (pos == string::npos) {
        cout << "0\n";
    } else {
        cout << result.substr(pos) << '\n';
    }
    return 0;
}

Problem 8: Ancient Chinese Text Layout

Arrange text vertically in columns from right to left, following ancient Chinese writing style.

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main() {
    int colCount;
    cin >> colCount;
    cin.ignore();
    
    string text;
    getline(cin, text);
    
    // Pad to multiple of column count
    while (text.length() % colCount != 0) {
        text += ' ';
    }
    
    // Reverse and output in columns
    reverse(text.begin(), text.end());
    
    for (int col = 0; col < colCount; col++) {
        for (size_t j = col; j < text.length(); j += colCount) {
            cout << text[j];
        }
        cout << '\n';
    }
    return 0;
}

Problem 9: Red Packet Statistics

Track red packet transactions and rank participants by total amount received and count.

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

struct Person {
    int id;
    int count = 0;
    long long amount = 0;
};

int main() {
    int n;
    scanf("%d", &n);
    
    vector<person> people(n + 1);
    for (int i = 1; i <= n; i++) {
        people[i].id = i;
    }
    
    for (int i = 1; i <= n; i++) {
        int k;
        scanf("%d", &k);
        long long sent = 0;
        
        for (int j = 0; j < k; j++) {
            int recipient, money;
            scanf("%d %d", &recipient, &money);
            sent += money;
            people[recipient].count++;
            people[recipient].amount += money;
        }
        people[i].amount -= sent;
    }
    
    sort(people.begin() + 1, people.end(), [](const Person& a, const Person& b) {
        if (a.amount != b.amount) return a.amount > b.amount;
        if (a.count != b.count) return a.count > b.count;
        return a.id < b.id;
    });
    
    for (int i = 1; i <= n; i++) {
        printf("%d %.2lf\n", people[i].id, people[i].amount / 100.0);
    }
    return 0;
}
</person>

Problem 10: Family Property

Use Union-Find to group family members and calculate total property statistics per family.

#include <cstdio>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;

int parent[10005];
bool exists[10005];
int houseCount[10005], area[10005];
int familySize[10005], minId[10005];
int familyHouse[10005], familyArea[10005];

int find(int x) {
    return parent[x] == x ? x : parent[x] = find(parent[x]);
}

void unite(int a, int b) {
    int pa = find(a), pb = find(b);
    if (pa != pb) {
        parent[pb] = pa;
    }
}

int main() {
    iota(parent, parent + 10005, 0);
    
    int n;
    scanf("%d", &n);
    
    while (n--) {
        int id, father, mother, k, houses, totalArea;
        scanf("%d %d %d %d", &id, &father, &mother, &k);
        
        exists[id] = true;
        
        if (father != -1) {
            exists[father] = true;
            unite(id, father);
        }
        if (mother != -1) {
            exists[mother] = true;
            unite(id, mother);
        }
        
        for (int i = 0; i < k; i++) {
            int child;
            scanf("%d", &child);
            exists[child] = true;
            unite(id, child);
        }
        
        scanf("%d %d", &houses, &totalArea);
        houseCount[id] = houses;
        area[id] = totalArea;
    }
    
    vector<tuple double="" int="">> results;
    
    for (int i = 0; i < 10000; i++) {
        if (exists[i]) {
            int root = find(i);
            familySize[root]++;
            familyHouse[root] += houseCount[i];
            familyArea[root] += area[i];
            if (minId[root] == 0 || i < minId[root]) {
                minId[root] = i;
            }
        }
    }
    
    for (int i = 0; i < 10000; i++) {
        if (familySize[i] > 0) {
            double avgHouse = familyHouse[i] * 1.0 / familySize[i];
            double avgArea = familyArea[i] * 1.0 / familySize[i];
            results.push_back({-avgArea, avgHouse, minId[i], familySize[i]});
        }
    }
    
    sort(results.begin(), results.end());
    
    printf("%d\n", results.size());
    for (auto& [negArea, avgHouse, id, size] : results) {
        printf("%04d %d %.3lf %.3lf\n", id, size, avgHouse, -negArea);
    }
    return 0;
}
</tuple>

Problem 11: Kung Fu Inheritance

Use DFS to traverse the martial arts lineage tree and calculate total combat power passed down through generations.

#include <cstdio>
#include <vector>
using namespace std;

vector<int> students[100005];
int isDisciple[100005];
double combat[100005];
double decayRate;
double totalPower = 0;

void dfs(int node, double power) {
    if (isDisciple[node] > 0) {
        totalPower += power * isDisciple[node];
        return;
    }
    
    for (int student : students[node]) {
        dfs(student, power * (100 - decayRate) / 100);
    }
}

int main() {
    int n;
    scanf("%d", &n);
    scanf("%lf %lf", &combat[0], &decayRate);
    
    for (int i = 0; i < n; i++) {
        int count;
        scanf("%d", &count);
        
        if (count == 0) {
            scanf("%d", &isDisciple[i]);
        } else {
            for (int j = 0; j < count; j++) {
                int student;
                scanf("%d", &student);
                students[i].push_back(student);
            }
        }
    }
    
    dfs(0, combat[0]);
    printf("%d\n", (int)totalPower);
    return 0;
}
</int>

Problem 12: Linked List Deduplication

Remove duplicate absolute values from a linked list, keeping first occurrences and collecting removed nodes separately.

#include <cstdio>
#include <set>
using namespace std;

struct Node {
    int data;
    int next;
};

Node memory[100005];

int main() {
    int startAddr, n;
    scanf("%d %d", &startAddr, &n);
    
    for (int i = 0; i < n; i++) {
        int addr, data, next;
        scanf("%d %d %d", &addr, &data, &next);
        memory[addr].data = data;
        memory[addr].next = next;
    }
    
    set<int> seen;
    int uniqueList[100005], uniqueCount = 0;
    int removedList[100005], removedCount = 0;
    
    int current = startAddr;
    while (current != -1) {
        int absVal = memory[current].data < 0 ? -memory[current].data : memory[current].data;
        
        if (seen.count(absVal)) {
            removedList[removedCount++] = current;
        } else {
            seen.insert(absVal);
            uniqueList[uniqueCount++] = current;
        }
        current = memory[current].next;
    }
    
    for (int i = 0; i < uniqueCount; i++) {
        printf("%05d %d ", uniqueList[i], memory[uniqueList[i]].data);
        if (i == uniqueCount - 1) printf("-1\n");
        else printf("%05d\n", uniqueList[i + 1]);
    }
    
    for (int i = 0; i < removedCount; i++) {
        printf("%05d %d ", removedList[i], memory[removedList[i]].data);
        if (i == removedCount - 1) printf("-1\n");
        else printf("%05d\n", removedList[i + 1]);
    }
    
    return 0;
}
</int>

Tags: C++ Competitive Programming algorithms Data Structures Union-Find

Posted on Sat, 09 May 2026 19:24:39 +0000 by AndyEarley