하루하루 꾸준히, 인생은 되는대로

자료구조

백준 23056 참가자 명단 C++

긤효중 2022. 6. 1. 23:28

https://www.acmicpc.net/problem/23056

 

23056번: 참가자 명단

첫째 줄에 학급 수인 $N$과 학급당 신청 가능한 인원수 $M$이 주어진다. ($N$은 짝수이고 $2\leq N \leq 10$, $1\leq M \leq 10$) 둘째 줄부터 신청된 순서대로 학생의 학급과 이름이 주어진다. 학생의 학급은

www.acmicpc.net

문제

 


 

백남이의 모교인 백준고등학교에서 체육대회를 개최하려 한다.

백남이는 학생들의 체육대회 신청을 관리하게 되었다.

체육대회는 1부터 N까지의 학급만 참여하며, 각 학급당 최대 M명까지 선착순으로 참가할 수 있다. 단, N은 짝수이다.

또한, 체육대회의 팀을 학급이 홀수일 때 청팀, 짝수일 때 백팀으로 나누기로 했다.

이에 따라 백남이는 체육대회 참가자 명단 프로그램을 제작하려 한다.

  • 청팀을 먼저, 백팀을 나중에 출력한다.
  • 각각의 팀에 대해 학급을 오름차순으로 출력한다.
  • 각각의 학급에 대해 학생의 이름을 길이가 짧은 것부터, 길이가 같다면 사전 순으로 출력한다.

입력

첫째 줄에 학급 수인 N과 학급당 신청 가능한 인원수 M이 주어진다. (N은 짝수이고 2≤N≤10 , 1≤M≤10

둘째 줄부터 신청된 순서대로 학생의 학급과 이름이 주어진다. 학생의 학급은 M을 초과하지 않는다. 이름은 모두 소문자이며 15자를 초과하지 않는다.

학급과 이름이 동일한 학생은 존재하지 않는다.

신청할 수 있는 최대 학생 수는 500명이다.

입력의 마지막은 0 0으로 나타낸다.


출력

첫째 줄부터 백남이의 체육대회 참가자 명단 프로그램에 맞게 학생의 학급과 이름을 공백으로 구분하여 출력한다.


청팀을 먼저 출력하고, 백팀을 나중에 출력한다.

참가자에 대한 구조체를 선언하고 구조체에 청팀인지 백팀인지 , 학급과 이름을 나타내야 한다.

학생의 학급이 N을 초과하지 않기 떄문에 map에 학급의 수를 넣어두고 N을 초과하지 않는다면 구조체 배열에 청팀인지 백팀인지 여부, 학급과 이름을 넣어둔다.

구조체에 대해 정렬을 하는데, cmp를 따로 설정해줘서 청팀이 먼저오고, 백팀이 나중에 오는순서대로, 학급에 대해 오름차순으로, 이름을 사전순으로 정렬을 시켜주면 된다.

 

#include <iostream>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
//1일떄 청팀,2일떄 백팀 -> 정렬시 청팀이 백팀보다 앞에 위치해야 한다
 
struct student{ //참가자에 대한 구조체
    int team; //청팀인지 백팀인지 여부
    int number; //학급의 번호
    string name; //이름에 대한 정보
};
 
typedef struct student d;

bool cmp(d a,d b){ //구조체를 정렬 할 cmp 함수
 
    if(a.team != b.team){ //청팀먼저 오도록 설정
        return a.team < b.team;
    }
 
    if(a.team == b.team){ //청팀이거나 , 백팀일떄 학급을 오름차순 정렬
        if(a.number != b.number){
            return a.number < b.number;
        }
 
    }
 
    if(a.number == b.number){ //학급이 같다면 이름을 사전순으로 정렬
        if(a.name.size() != b.name.size()){
            return a.name.size() < b.name.size();
        }
        else if(a.name.size() == b.name.size()){
            return a.name < b.name;
        }
    }
 
}
int main(void){
    map<int,int> m;
    map<int,int>::iterator iter; //학급의 등장 횟수를 저장할 map
 
    d arr[1000]; //구조체 배열 선언
 
    int n,count;
    cin >> n >> count;
    int index = 0;
 
    while(1){
        int room;
        string str;
        cin >> room;
        cin >> str;
        if(room == 0 && str == "0"){ //입력의 마지막
            break;
        }
        
        iter = m.find(room);
        int value = iter->second;
        
        if(iter == m.end()){ //map에 없다면
            m[room]++; //map에 넣어두고
            if(room%2 == 0){ //백팀이라면
            arr[index].team = 2;
            arr[index].number = room;
            arr[index].name = str;
        }
        else if(room%2 != 0){ //청팀이라면
            arr[index].team = 1;
            arr[index].number = room;
            arr[index].name = str;
        }
        }
 
        else if(value < count){ //등장횟수가 m을 초과하지 않는 조건에서
            m[room]++; //마찬가지로 map에 넣고, 백팀,청팀 구분하기
             if(room%2 == 0){
            arr[index].team = 2;
            arr[index].number = room;
            arr[index].name = str;
        }
        else if(room%2 != 0){
            arr[index].team = 1;
            arr[index].number = room;
            arr[index].name = str;
        }
        } 
        index++;
    }
 
    sort(arr,arr+index,cmp); //정렬 후 출력
    for(int i = 0;i<index;i++){
        if(arr[i].number != 0){
            cout << arr[i].number << ' ' << arr[i].name << '\n';
        }
    }
}

'자료구조' 카테고리의 다른 글

백준 20044 Project Teams C++  (0) 2022.06.15
백준 1991 트리 순회 C++  (0) 2022.06.03
백준 수 정렬하기 3  (0) 2022.05.20
2022-05-15 알고리즘 문제  (0) 2022.05.15
백준 12789 도키도키 간식드리미 C++  (0) 2022.05.01