https://school.programmers.co.kr/learn/courses/30/lessons/92334
게시판 불량 이용자를 신고하고 처리 결과를 메일로 발송하는 시스템
유저는 한번에 한 유저를 신고한다. - 한사람당 여러명 신고가능, 하지만 신고 한 사람은 재신고 불가능
k번 이상 신고된 유저는 게시판 이용이 정지된다. - 유저가 신고한 모든 내용을 취합하여 정지 메일을 보낸다.
조건1. id_list는 2~1000
조건2. report는 1~20만
조건3. k는 1~200
구해야하는 값 : id_list에 담긴 id 순서대로 각 유저가 받은 메일 수
이 문제는 구현을 하는 문제였다.
여러개의 배열와 map을 써야한다는 점에서 꽤나 곤욕을 주기 좋은 문제였다.
문제의 풀이는 간단하다.
제일 먼저 생각한 점은 일단 id_list와 배열의 index와의 매핑이었다. 이 매핑은 해시테이블을 사용하여 구현하였다.
그리고,
report에 대하여 반복문을 돌면서 report를 먼저 split해주고,
그렇게 나온 두개의 문자열을 통해서 누가 누구를 신고 했는지 알 수 있게된다.
중복된 신고는 필터 해주어야 하므로, 이를 기억하기 위해서 map을 사용하여 중복 신고를 막아주었다.
그리고 이렇게 신고를 한 마지막 결과를 통보해주기 위해서는 누가 누구를 신고 했는지 또한 배열에 저장을 해주면 좋을 것이다.
그래서 이를 배열에 저장을 해주었다.
그리고 유저가 신고당한 횟수를 배열에 저장해주었다.
그리고 마지막으로 결과를 얻기 위하여, k와 유저가 신고당한 횟수를 저장한 배열의 값들을 비교하여
정지당 할 아이디를 신고한 사람들에게 메일을 보내주었다.
#include <string>
#include <vector>
#include <map>
#include <sstream>
using namespace std;
vector<int> solution(vector<string> id_list, vector<string> report, int k) {
vector<int> answer(id_list.size());
vector<int> cnt(id_list.size());
map<string,int> pos;
map<pair<string,string>, bool> visit;
vector<vector<int> > reported(id_list.size());
for(int i=0;i<id_list.size();i++)
{
pos.insert(make_pair(id_list[i],i));
}
for(int i=0;i<report.size();i++)
{
istringstream ss(report[i]);
string stringBuffer;
vector<string> s;
while (getline(ss, stringBuffer, ' ')){
s.push_back(stringBuffer);
}
pair<string,string> x = make_pair(s[0],s[1]);
if(visit.find(x) == visit.end())
{
visit.insert(make_pair(make_pair(s[0],s[1]),true));
cnt[pos[s[1]]]++;
reported[pos[s[1]]].push_back(pos[s[0]]);
}
}
for(int i=0;i<cnt.size();i++)
{
if(cnt[i] >= k)
{
for(int j=0;j<reported[i].size();j++)
{
answer[reported[i][j]]++;
}
}
}
return answer;
}