[백준/BOJ] 백준 25240번 : 가희와 파일 탐색기 2

2023. 4. 11. 03:28알고리즘 문제풀이

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

 

25240번: 가희와 파일 탐색기 2

Q개의 질문에 대해, 연산이 성공하면 1을 실패하면 0을 출력해 주세요. 각 질문에 대한 답은 한 줄에 하나씩 출력해 주세요.

www.acmicpc.net

 

유저마다 어떤 그룹에 속하는지 정보를 저장해 놓고, 유저가 특정 파일에 가지는 권한을 확인할 때, 유저가 파일의 소유자 인지 확인하고, 유저가 속한 그룹들 중 해당 파일의 소유 그룹이 있는지 확인하는 방법을 통해 문제를 해결했다.

 

코드

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
using namespace std;

int u, f;
int q;
map<string, tuple<string, string, string>> file_info; //[파일이름] = (파일 권한, 소유자, 소유그룹)
map<string, vector<string>> user_info; //[유저 이름] = {유저가 속한 그룹들}
vector<int> result;

int main()
{
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> u >> f;

	cin.ignore();
	for (int i = 0; i < u; i++) {

		string input;

		string user_name;
		string user_groups;
		vector<string> groups;

		getline(cin, input);

		//유저 그룹 정보가 따로 없을때
		if (input.find(' ') == string::npos) {
			user_name = input;
			groups.push_back(user_name);
			user_info.insert(make_pair(user_name, groups));
			continue;
		}

		int groups_index = input.find(' ');
		user_name = input.substr(0, groups_index);
		user_groups = input.substr(groups_index + 1);

		int start_index = 0;
		while (1) {

			string group;
			if (user_groups.find(',', start_index) == string::npos) {
				group = user_groups.substr(start_index);
				groups.push_back(group);
				break;
			}

			int find_index = user_groups.find(',', start_index);

			group = user_groups.substr(start_index, find_index - start_index);
			groups.push_back(group); //그룹 정보 추가

			start_index = find_index + 1;
		}
		groups.push_back(user_name); //자기 이름을 그룹 정보에 추가

		user_info.insert(make_pair(user_name, groups));
	}

	for (int i = 0; i < f; i++) {
		string file_name, file_permission, owner, owned_group;

		cin >> file_name >> file_permission >> owner >> owned_group;
		file_info.insert(make_pair(file_name, make_tuple(file_permission, owner, owned_group)));
	}

	cin >> q;

	for (int i = 0; i < q; i++) {
		string user_name, file_name, operation;

		cin >> user_name >> file_name >> operation;

		vector<string> user_groups = user_info[user_name]; //사용자가 속한 그룹들
		tuple<string, string, string> file_status = file_info[file_name]; //(파일 권한, 소유자, 소유그룹)

		int check = 2; //(user가 file의 소유자면 0, 소유 그룹이면 1, 소유자도 아니고 소유그룹도 아니면 2)

		if (get<1>(file_status) == user_name) { //해당 파일의 소유자 일때
			check = 0;
		}

		else {
			//사용자가 속한 그룹들 확인
			for (int g = 0; g < user_groups.size(); g++) {
				if (get<2>(file_status) == user_groups[g]) { //해당 파일의 소유그룹에 속할때
					check = 1;
					break;
				}
			}
		}

		int file_check = stoi(get<0>(file_status).substr(check, 1)); //해당 사용자가 해당 파일에 가지고 있는 권한

		if (operation == "R") {
			if ((file_check & (1 << 2)) != 0) {
				result.push_back(1);
			}

			else {
				result.push_back(0);
			}

		}

		else if (operation == "W") {
			if ((file_check & (1 << 1)) != 0) {
				result.push_back(1);
			}

			else {
				result.push_back(0);
			}
		}

		else {
			if ((file_check & (1 << 0)) != 0) {
				result.push_back(1);
			}

			else {
				result.push_back(0);
			}
		}
	}

	for (int i = 0; i < result.size(); i++) {
		cout << result[i] << "\n";
	}

	return 0;
}