Participants Present at Every Contest
National Olympiad — Municipal round (2013 season)
Submission name: all.cpp
Problem summary
Each contest supplies a zero-terminated list of participant IDs. Print the IDs that occur in every contest, in increasing order, or 0 if none do.
Input
The number N of contests, followed by N participant lists, each ending in 0.
Output
Common participant IDs separated by spaces, or 0.
Constraints
1 ≤ N < 21; IDs are in [1,K] with 0 < K < 221. K is not an input field.
Worked example
Input and output for the worked example discussed below.
Input
3 2 3 8 12 34 20 21 22 33 0 11 13 17 22 6 8 33 41 45 9 0 6 11 8 17 33 9 22 0
Output
8 22 33
Solution analysis
- An ID belongs in the answer exactly when it has appeared in all N lists. Use an occurrence counter per possible ID, counting at most once per contest.
- Read a whole list until its zero sentinel. A per-list boolean array prevents accidental duplicate IDs in one list from inflating the count. After all lists, scan IDs in increasing order and print those whose count is N.
- In the sample, 8,22,33 occur in all three lists. An ID such as 11 is missing from the first and cannot qualify. A fixed scan over the bounded ID range produces sorted output without a separate sorting step.
Why it works
After processing c contests, an ID’s counter equals the number of those contests containing it. Thus its final counter equals N exactly for the intersection of all lists. The increasing-ID scan emits precisely this intersection in the required order.
Watch out. Zero terminates a list and is not a participant. N is followed directly by lists; there is no input K. The PDF’s bound is K<221, not 2^21. Print 0 only for an empty intersection.
Commented C++17 solution
An independently written complete program with standard headers.
#include<algorithm>
#include<array>
#include<cmath>
#include<iostream>
#include<limits>
#include<map>
#include<numeric>
#include<set>
#include<string>
#include<vector>
using namespace std;
int main(){
int contests;
cin>>contests;
array<int,221>appearances{};
for(int contest=0;contest<contests;contest++){
array<bool,221>seen{};
int id;
while(cin>>id&&id!=0){
seen[id]=true;
}
// Duplicate entries in one contest still count as a single appearance.
for(int participant=1;participant<=220;participant++){
appearances[participant]+=seen[participant];
}
}
bool printed=false;
for(int id=1;id<=220;id++){
if(appearances[id]==contests){
if(printed){
cout<<' ';
}
cout<<id;
printed=true;
}
}
if(!printed){
cout<<0;
}
cout<<'\n';
}