Problem Overview
In a competitive selection process, $n$ judges vote for $m$ available brands using a multi-round elimination system. The goal is to determine if a single brand can emerge as the winner or if the selection fails due to a tie in the final round.
Elimination Rules
The process follows these logic steps until a result is determined:
- Voting: In each round, every judge casts a vote for their preferred brand among those that have not yet been eliminated.
- Preferences: Each judge provides a sequence of brands (e.g., "351"). They vote for brand 3 first. If 3 is eliminated, they vote for 5. If 3 and 5 are both eliminated, they vote for 1. A '0' in the sequence indicates an abstention if no prior brands are available.
- Elimination: The brand(s) receiving the minimum number of votes in the current round are eliminated.
- Success: If exact one brand remains after a round, that brand is declared the winner.
- Failure: If all remaining brands (two or more) receive the same minimum number of votes in a single round, they are all eliminated simultaneously, and the selection fails.
Output Requirements
If a winner is found, output the brand ID. If the selection fails, output the negative value of the vote count received by the brands in the final round of the tie.
Implementation in C++
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main() {
int brandCount, judgeCount;
if (!(cin >> brandCount >> judgeCount)) return 0;
vector<string> preferences(judgeCount);
for (int i = 0; i < judgeCount; ++i) {
cin >> preferences[i];
}
vector<bool> isEliminated(brandCount + 1, false);
int activeBrands = brandCount;
while (activeBrands > 1) {
vector<int> currentVotes(brandCount + 1, 0);
// Count votes for this round
for (int i = 0; i < judgeCount; ++i) {
for (char c : preferences[i]) {
int brandId = c - '0';
if (brandId == 0) break;
if (!isEliminated[brandId]) {
currentVotes[brandId]++;
break;
}
}
}
// Determine minimum votes among active brands
int minVoteValue = judgeCount + 1;
for (int i = 1; i <= brandCount; ++i) {
if (!isEliminated[i]) {
minVoteValue = min(minVoteValue, currentVotes[i]);
}
}
// Identify brands to eliminate
vector<int> toEliminate;
for (int i = 1; i <= brandCount; ++i) {
if (!isEliminated[i] && currentVotes[i] == minVoteValue) {
toEliminate.push_back(i);
}
}
// Check if all remaining brands are tied
if (toEliminate.size() == activeBrands) {
cout << -minVoteValue << endl;
return 0;
}
// Perform elimination
for (int brandId : toEliminate) {
isEliminated[brandId] = true;
activeBrands--;
}
// Check for winner
if (activeBrands == 1) {
for (int i = 1; i <= brandCount; ++i) {
if (!isEliminated[i]) {
cout << i << endl;
return 0;
}
}
}
}
return 0;
}
Logic Breakdown
The solution utilizes a boolean array isEliminated to track the status of each brand. In each iteration, we simulate the judges' choices by iterating through their preference strings. The activeBrands counter ensures we know when to terminate the loop. The critical edge case—where all remaining candidates are tied for the minimum—is handled by comparing the count of candidates marked to elimination against the current activeBrands count.