Programming Competition Solutions: RAICOM 2024 Provincial Contest
Problem 1: Free Drink Days
**Problem Description:**Given N consecutive days of temperature and the starting day of the week, calculate how many days you can get free drinks (when temperature ≥ 35°C) and how many days you couldn't get free drinks specifically because it was Thursday.
**Input Format:**First line contains two integers N (number of days) and W (starting day of week, where 1=Monday, 7=Sunday). Second line contains N integers representing temperatures for each day.
**Output Format:**Two integers - days with free drinks and days missed due to Thursday.
import java.util.Scanner;
public class FreeDrinkCalculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int dayCount = scanner.nextInt();
int startDay = scanner.nextInt();
int[] temperatures = new int[dayCount];
for (int i = 0; i < dayCount; i++) {
temperatures[i] = scanner.nextInt();
}
int[] result = calculateFreeDrinkDays(dayCount, startDay, temperatures);
System.out.println(result[0] + " " + result[1]);
}
public static int[] calculateFreeDrinkDays(int days, int firstDay, int[] temps) {
int eligibleDays = 0;
int thursdayPenalty = 0;
for (int i = 0; i < days; i++) {
int currentTemp = temps[i];
int currentDay = (firstDay + i - 1) % 7 + 1;
if (currentTemp >= 35) {
eligibleDays++;
}
if (currentDay == 4 && currentTemp >= 35) {
thursdayPenalty++;
eligibleDays--;
}
}
return new int[]{eligibleDays, thursdayPenalty};
}
}
Problem 2: Tournament Qualification
**Problem Description:**Calculate final scores for teams in a tournament where each team's score is based on their ranking and number of eliminations in each match.
**Input Format:**First line contains N (number of matches). For each match, there are 20 lines with two integers: position and eliminations for each team.
**Output Format:**20 lines showing each team's final score.
import java.util.Scanner;
public class TournamentScorer {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int matchCount = scanner.nextInt();
int[] teamScores = new int[21]; // Using 1-based indexing
int[] rankPoints = initializeRankPoints();
for (int i = 0; i < matchCount * 20; i++) {
int position = scanner.nextInt();
int eliminations = scanner.nextInt();
int teamIndex = (i % 20) + 1;
teamScores[teamIndex] += eliminations + rankPoints[position];
}
for (int i = 1; i <= 20; i++) {
System.out.println(i + " " + teamScores[i]);
}
}
private static int[] initializeRankPoints() {
int[] points = new int[21];
points[1] = 12;
points[2] = 9;
points[3] = 7;
points[4] = 5;
points[5] = 4;
for (int i = 6; i <= 7; i++) points[i] = 3;
for (int i = 8; i <= 10; i++) points[i] = 2;
for (int i = 11; i <= 15; i++) points[i] = 1;
for (int i = 16; i <= 20; i++) points[i] = 0;
return points;
}
}
Problem 3: Hidden Stoves
**Problem Dsecription:**In a grid containing capybaras (cold 'c' or warm 'w') and stoves 'm', find positions where a hidden stove could be placed to warm all capybaras.
**Input Format:**First line contains N and M (grid dimensions). Next N lines contain M characters each representing the grid state.
**Output Format:**All possible positions for hidden stoves, sorted by row then column, or "Too cold!" if no solutions.
import java.util.Scanner;
public class HiddenStoveFinder {
static boolean solutionFound = false;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int rows = scanner.nextInt();
int cols = scanner.nextInt();
scanner.nextLine();
char[][] grid = new char[rows][cols];
for (int i = 0; i < rows; i++) {
grid[i] = scanner.nextLine().toCharArray();
}
// Look for warm capybaras without adjacent stoves
for (int i = 1; i < rows - 1; i++) {
for (int j = 1; j < cols - 1; j++) {
if (grid[i][j] == 'w' && !hasAdjacentStove(grid, i, j)) {
checkPossibleStoveLocations(grid, i, j);
if (!solutionFound) {
System.out.println("Too cold!");
}
return;
}
}
}
System.out.println("Too cold!");
}
private static boolean hasAdjacentStove(char[][] grid, int row, int col) {
return grid[row-1][col-1] == 'm' || grid[row-1][col] == 'm' || grid[row-1][col+1] == 'm' ||
grid[row][col-1] == 'm' || grid[row][col+1] == 'm' ||
grid[row+1][col-1] == 'm' || grid[row+1][col] == 'm' || grid[row+1][col+1] == 'm';
}
private static void checkPossibleStoveLocations(char[][] grid, int capyRow, int capyCol) {
int[] rows = {-1, -1, -1, 0, 0, 1, 1, 1};
int[] cols = {-1, 0, 1, -1, 1, -1, 0, 1};
for (int i = 0; i < 8; i++) {
int r = capyRow + rows[i];
int c = capyCol + cols[i];
if (grid[r][c] == '.' && !hasAdjacentColdCapybara(grid, r, c)) {
System.out.println((r + 1) + " " + (c + 1));
solutionFound = true;
}
}
}
private static boolean hasAdjacentColdCapybara(char[][] grid, int row, int col) {
int[] rows = {-1, -1, -1, 0, 0, 1, 1, 1};
int[] cols = {-1, 0, 1, -1, 1, -1, 0, 1};
for (int i = 0; i < 8; i++) {
int r = row + rows[i];
int c = col + cols[i];
if (grid[r][c] == 'c') {
return true;
}
}
return false;
}
}
Problem 4: Octopus Graph Detection
**Problem Description:**Determine if a graph is an "octopus graph" (exactly one cycle) and count the number of such subgraphs.
**Input Format:**First line contains T (number of test cases). For each test case, first line contains N and M (vertices and edges). Next M lines contain pairs of vertices representing edges.
**Output Format:**For each test case, output "Yes X" if exactly one octopus subgraph exists (X being cycle size), or "No Y" if not (Y being number of octopus subgraphs).
import java.util.*;
public class OctopusGraphDetector {
static List<list>> graph;
static boolean[] visited;
static int[] parent;
static int[] depth;
static List<integer> cycleVertices;
static int cycleCount;
static boolean hasCycle;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int testCases = scanner.nextInt();
while (testCases-- > 0) {
int vertices = scanner.nextInt();
int edges = scanner.nextInt();
graph = new ArrayList<>();
for (int i = 0; i <= vertices; i++) {
graph.add(new ArrayList<>());
}
for (int i = 0; i < edges; i++) {
int u = scanner.nextInt();
int v = scanner.nextInt();
graph.get(u).add(v);
graph.get(v).add(u);
}
visited = new boolean[vertices + 1];
parent = new int[vertices + 1];
depth = new int[vertices + 1];
cycleVertices = new ArrayList<>();
cycleCount = 0;
hasCycle = false;
for (int i = 1; i <= vertices; i++) {
if (!visited[i]) {
detectCycle(i);
}
}
if (cycleCount == 1) {
System.out.println("Yes " + cycleVertices.size());
} else {
System.out.println("No " + cycleCount);
}
}
}
private static void detectCycle(int start) {
Queue<integer> queue = new LinkedList<>();
queue.add(start);
visited[start] = true;
depth[start] = 0;
parent[start] = -1;
while (!queue.isEmpty()) {
int u = queue.poll();
for (int v : graph.get(u)) {
if (!visited[v]) {
visited[v] = true;
parent[v] = u;
depth[v] = depth[u] + 1;
queue.add(v);
} else if (parent[u] != v && depth[u] > depth[v]) {
// Found a cycle
hasCycle = true;
extractCycle(u, v);
cycleCount++;
}
}
}
}
private static void extractCycle(int u, int v) {
cycleVertices = new ArrayList<>();
// Add vertices from u to the common ancestor
while (u != v && u != -1) {
cycleVertices.add(u);
u = parent[u];
}
if (u != -1) {
cycleVertices.add(u);
}
// Add vertices from v to the common ancestor (excluding the common ancestor)
List<integer> tempPath = new ArrayList<>();
while (v != u && v != -1) {
tempPath.add(v);
v = parent[v];
}
// Add in reverse order
for (int i = tempPath.size() - 1; i >= 0; i--) {
cycleVertices.add(tempPath.get(i));
}
}
}</integer></integer></integer></list>
Problem 5: Job Scheduling
**Problem Description:**Schedule jobs with deadlines to maximize total profit, where each job has a time requirement, deadline, and profit.
**Input Format:**First line contains T (number of test cases). For each test case, first line contains N (number of jobs). Next N lines contain three integers: time required, deadline, and profit for each job.
**Output Format:**Maximum achievable profit for each test case.
import java.util.*;
public class JobScheduler {
static class Task {
int timeRequired;
int deadline;
int profit;
Task(int t, int d, int p) {
this.timeRequired = t;
this.deadline = d;
this.profit = p;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int testCases = scanner.nextInt();
while (testCases-- > 0) {
int jobCount = scanner.nextInt();
Task[] jobs = new Task[jobCount];
for (int i = 0; i < jobCount; i++) {
int time = scanner.nextInt();
int deadline = scanner.nextInt();
int profit = scanner.nextInt();
jobs[i] = new Task(time, deadline, profit);
}
System.out.println(calculateMaxProfit(jobs));
}
}
private static int calculateMaxProfit(Task[] jobs) {
// Sort jobs by deadline
Arrays.sort(jobs, Comparator.comparingInt(task -> task.deadline));
// Initialize DP array
int maxDeadline = Arrays.stream(jobs).mapToInt(task -> task.deadline).max().orElse(0);
int[] dp = new int[maxDeadline + 1];
for (Task job : jobs) {
// Update DP array in reverse order
for (int time = job.deadline; time >= job.timeRequired; time--) {
if (dp[time - job.timeRequired] + job.profit > dp[time]) {
dp[time] = dp[time - job.timeRequired] + job.profit;
}
}
}
// Find maximum profit
return Arrays.stream(dp).max().orElse(0);
}
}