Algorithm Solutions for Programming Contest Problems

Calendar Date Calculation

This problem involves calculating the day of the week for a given date using a simplified calendar system where each month has 30 days. The solution processes date comparisons and computes day differences with modulo operations.


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

int main() {
    unordered_map<string, int> dayToNum = {
        {"Monday", 0}, {"Tuesday", 1}, {"Wednesday", 2}, 
        {"Thursday", 3}, {"Friday", 4}
    };
    unordered_map<int, string> numToDay = {
        {0, "Monday"}, {1, "Tuesday"}, {2, "Wednesday"},
        {3, "Thursday"}, {4, "Friday"}
    };
    
    int testCases;
    cin >> testCases;
    while (testCases--) {
        int year1, month1, day1, year2, month2, day2;
        string startDay;
        cin >> year1 >> month1 >> day1 >> startDay >> year2 >> month2 >> day2;
        
        month1--; month2--;
        int date1 = month1 * 30 + day1;
        int date2 = month2 * 30 + day2;
        int result;
        
        if (year1 > year2) {
            int diff = (date1 + 360 - date2) % 5;
            result = (dayToNum[startDay] - diff + 5) % 5;
        } else if (year1 < year2) {
            int diff = (date2 + 360 - date1) % 5;
            result = (dayToNum[startDay] + diff) % 5;
        } else {
            if (date1 > date2) {
                int diff = (date1 - date2) % 5;
                result = (dayToNum[startDay] - diff + 5) % 5;
            } else {
                int diff = (date2 - date1) % 5;
                result = (dayToNum[startDay] + diff) % 5;
            }
        }
        cout << numToDay[result] << endl;
    }
    return 0;
}

Robot Path Optimization

This solution calculates the maximum Mahnattan distance reached by a robot following a repeating path. It processes the path once to determine the endpoint, then combines this with the final iteration.


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

int main() {
    int tests;
    cin >> tests;
    while (tests--) {
        int length, repetitions;
        cin >> length >> repetitions;
        string moves;
        cin >> moves;
        
        int x = 0, y = 0, maxDist = 0;
        for (char move : moves) {
            if (move == 'R') x++;
            else if (move == 'L') x--;
            else if (move == 'U') y++;
            else y--;
            maxDist = max(maxDist, abs(x) + abs(y));
        }
        
        x *= (repetitions - 1);
        y *= (repetitions - 1);
        
        if (repetitions > 1) {
            for (char move : moves) {
                if (move == 'R') x++;
                else if (move == 'L') x--;
                else if (move == 'U') y++;
                else y--;
                maxDist = max(maxDist, abs(x) + abs(y));
            }
        }
        cout << maxDist << endl;
    }
    return 0;
}

Graph Game Analysis

This problem involves determining the winner in a graph edge removal game. The solution calculates the maximum number of moves possible based on graph connectivity.


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

int main() {
    int testCount;
    cin >> testCount;
    while (testCount--) {
        int playerCount;
        string players;
        cin >> playerCount >> players;
        int vertices, edges;
        cin >> vertices >> edges;
        for (int i = 0; i < edges; i++) {
            int u, v;
            cin >> u >> v;
        }
        int moves = edges - (vertices - 1);
        int loserIndex = moves % playerCount;
        if (players[loserIndex] == '1') cout << 2 << endl;
        else cout << 1 << endl;
    }
    return 0;
}

Bucket Stone Distribution

This algorithm balances stones across buckets by calculating the minimum operations needed to achieve equal distribution or remove excess stones.


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

int main() {
    int testCases;
    cin >> testCases;
    while (testCases--) {
        int bucketCount;
        cin >> bucketCount;
        vector<int> stones(bucketCount);
        int total = 0;
        for (int i = 0; i < bucketCount; i++) {
            cin >> stones[i];
            total += stones[i];
        }
        int target = total / bucketCount;
        int operations = total % bucketCount;
        for (int count : stones) {
            operations += max(target - count, 0);
        }
        cout << operations << endl;
    }
    return 0;
}

Segment Token Placement

This solution maximizes token placement on segments using a priority queue to always select the segment with smallest left endpoint.


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

struct Segment {
    int left, right;
    Segment(int l, int r) : left(l), right(r) {}
    bool operator<(const Segment& other) const {
        if (left == other.left) return right > other.right;
        return left > other.left;
    }
};

int main() {
    int testCount;
    cin >> testCount;
    while (testCount--) {
        int segmentCount;
        cin >> segmentCount;
        priority_queue<Segment> segments;
        for (int i = 0; i < segmentCount; i++) {
            int l, r;
            cin >> l >> r;
            segments.push(Segment(l, r));
        }
        
        int currentPos = 0, placed = 0;
        while (!segments.empty()) {
            Segment seg = segments.top();
            segments.pop();
            
            if (seg.left <= currentPos && seg.left + 1 <= seg.right) {
                segments.push(Segment(seg.left + 1, seg.right));
                continue;
            }
            if (seg.left > currentPos) {
                placed++;
                currentPos = seg.left;
            }
        }
        cout << placed << endl;
    }
    return 0;
}

Median Candidate Verification

This algorithm verifies if numbers can be medians in a directed graph by counting predecessors and successors using BFS, detecting cycles in the process.


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

void process() {
    int n, m;
    cin >> n >> m;
    vector<vector<int>> graph(n + 1);
    for (int i = 0; i < m; i++) {
        int from, to;
        cin >> from >> to;
        graph[from].push_back(to);
    }
    
    vector<int> predecessors(n + 1, 0), successors(n + 1, 0);
    vector<int> visited(n + 1, 0);
    
    auto traverse = [&](int start) -> bool {
        queue<int> q;
        q.push(start);
        visited[start] = start;
        
        while (!q.empty()) {
            int current = q.front();
            q.pop();
            
            for (int neighbor : graph[current]) {
                if (neighbor == start) return false;
                if (visited[neighbor] == start) continue;
                
                q.push(neighbor);
                visited[neighbor] = start;
                predecessors[neighbor]++;
                successors[start]++;
            }
        }
        return true;
    };
    
    for (int i = 1; i <= n; i++) {
        if (!traverse(i)) {
            cout << string(n, '0') << endl;
            return;
        }
    }
    
    for (int i = 1; i <= n; i++) {
        if (predecessors[i] * 2 <= n && successors[i] * 2 <= n)
            cout << '1';
        else
            cout << '0';
    }
    cout << endl;
}

int main() {
    int testCases;
    cin >> testCases;
    while (testCases--) process();
    return 0;
}

Number Halving Simulation

This solution simulates repeated halving of a number with ceiling rounding, stopping when the value reaches 1.


#include <iostream>
using namespace std;

int main() {
    int testCases;
    cin >> testCases;
    while (testCases--) {
        int number, iterations;
        cin >> number >> iterations;
        for (int i = 0; i < iterations; i++) {
            if (number > 1) number = (number + 1) / 2;
            else break;
        }
        cout << number << endl;
    }
    return 0;
}

Tags: calendar-calculation graph-theory priority-queue bfs-algorithm manhattan-distance

Posted on Mon, 24 Aug 2026 16:00:59 +0000 by smnovick