최's 먹공로그
BOJ25240 가희와 파일 탐색기2 본문
<문제 요약>
https://www.acmicpc.net/problem/25240
(1) 3개의 숫자 중
첫번 째 숫자 : 파일을 소유하고 있는 유저가 어떤 권한을 가지고 있는지를 나타냄
두번 째 숫자 : 파일을 소유하고 있는 그룹이 어떤 권한을 가지고 있는지
세번 째 숫자 : 파일을 소유하고 있는 그룹에 속하지 않고, 파일을 소유하고 있는 유저가 아닌 경우 어떤 권한을 가지고 있는지
(2) 입력
-. 유저에 대한 정보 U, 파일에 대한 정보 F
-. U개의 유저 정보
USER_NAME
USER_NAME, USER_GROUPS 유저가 속한 그룹이 여러 개라면 ,로 구분
USER_NAME은 자동으로 그룹 이름이 USER_NAME 인 그룹에 속함
※ 유저가 속한 그룹들에 대한 정보에 USER_NAME이 주어지지 않더라도 그룹 이름이 USER_NAME인 그룹에 속함
-. 파일 정보
FIME_NAME FIME_PERMISSION OWNER OWNED_GROUP
파일이름 파일 권한 소유자 소유그룹
-. 질문정보
질문 개수 Q
USER_NAME FILE_NAME OPERATION(R읽기,W수정,X실행)
(3) 출력
Q개의 질문에 대해 연산이 성공하면 1 실패하면 0 각 질문에 대한 답은 한 줄에 하나씩 출력
<풀이흐름, Source Code>
(1) User정보는 HashMap<String UserName, HashSet<String GroupName>>에 저장
File정보는 HashMap<String FileName, FileInfo>에 저장한다. FileInfo는 권한, 소유자 이름, 소유그룹 이름을 갖는다.
(2) UserName과 GroupName을 입력 받아서 UserList에 넣는다. 이 때, Group이 여러개면 ','로 구분된다는 점과 GroupName이 없으면 UserName = GroupName이라는 점 그리고 GroupName이 있어도 UserName이 GroupName도 된다는 점을 주의한다.
(3) FileName과 FileInfo를 입력 받아서 FileList에 넣어준다.
파일에 대한 권한의 경우 754 이런식으로 3글자로 들어오는데 이를 2진수로 검사해줄 예정
숫자 | 권한 | 2진수 |
0 | 아무것도 할 수 없음 | 0000 |
1→X | 실행 권한이 있음 | 0001 |
2→W | 수정 권한이 있음 | 0010 |
3 | 실행 권한과 수정 권한이 있음 | 0011 |
4→R | 읽기 권한이 있음 | 0100 |
5 | 읽기와 실행 권한이 있음 | 0101 |
6 | 읽기와 수정 권한이 있음 | 0110 |
7 | 읽기와 실행, 수정 권한이 있음 | 0111 |
754인 경우 arr_permission[OWNER = 0] = 7, arr_permission[GROUP = 1] = 5, arr_permission[GUEST = 2] = 4와 같이 저장 해준다.
(4) 질문은 UserName FileName Command 순서로 들어오는데 User가 File에 대해 Command를 할 수 있으면 1 없으면 0 이니깐 일단 Command를 숫자화 한다.(위 표 참고)
(5) 이제 순서대로 FileList에 소유자이름과 질문의 UserName을 비교 → FileList의 그룹이름과 UserName의 GroupName을 비교해서 권한을 & 연산으로 계산 해준다. 위 두개의 비교에서 같은 이름이 없으면 그냥 GUEST의 권한과 비교한다. 최종 권한이 질문의 권한과 동일하면 파일에 대한 권한이 있어서 return 1, 아니면 return 0
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.StringTokenizer;
public class BOJ25240_가희 {
private static class fileInfo {
String ownerName;
String ownerGroupName;
int[] arr_permission = new int[3];
fileInfo(int permission, String ownerName, String ownerGroupName) {
arr_permission[GUEST] = permission % 10;
permission /= 10;
arr_permission[GROUP] = permission % 10;
permission /= 10;
arr_permission[OWNER] = permission % 10;
this.ownerName = ownerName;
this.ownerGroupName = ownerGroupName;
}
}
static int U, F, Q;
static final int OWNER = 0, GROUP = 1, GUEST = 2;
static HashMap<String, HashSet<String>> userList = new HashMap<String, HashSet<String>>();
static HashMap<String, fileInfo> fileList = new HashMap<String, fileInfo>();
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
input();
}
private static void input() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
U = Integer.parseInt(st.nextToken());
F = Integer.parseInt(st.nextToken());
for (int iu = 0; iu < U; iu++) {
st = new StringTokenizer(br.readLine(), " ");
String strUserName = "";
String strGroupName = "";
if (st.countTokens() == 2) {
strUserName = st.nextToken();
strGroupName = st.nextToken();
} else if (st.countTokens() == 1) {
strUserName = st.nextToken();
strGroupName = strUserName;
}
if (!userList.containsKey(strUserName)) {
userList.put(strUserName, new HashSet<String>());
}
userList.get(strUserName).add(strUserName);// 사용자도 그룹임
String[] strTempGroupName = strGroupName.split(",");
for (String temp : strTempGroupName) {
userList.get(strUserName).add(temp);
}
}
for (int iif = 0; iif < F; iif++) {
st = new StringTokenizer(br.readLine(), " ");
String strFileName = st.nextToken();
fileInfo fi = new fileInfo(Integer.parseInt(st.nextToken()), st.nextToken(), st.nextToken());
fileList.put(strFileName, fi);
}
st = new StringTokenizer(br.readLine());
Q = Integer.parseInt(st.nextToken());
for (int qi = 0; qi < Q; qi++) {
st = new StringTokenizer(br.readLine(), " ");
int result = cal(st.nextToken(), st.nextToken(), st.nextToken());
sb.append(result);
sb.append("\n");
}
System.out.print(sb.toString());
}
private static int cal(String userName, String fileName, String oper) {
int iPermission = 0;
if (oper.equals("X"))
iPermission = 1;
else if (oper.equals("W"))
iPermission = 2;
else if (oper.equals("R"))
iPermission = 4;
int lastPermission = 0;
if (fileList.containsKey(fileName)) {
fileInfo fi = fileList.get(fileName);
String strownerName = fi.ownerName;
String strownerGroupName = fi.ownerGroupName;
int[] arrPermission = fi.arr_permission;
if (userName.equals(strownerName)) {
lastPermission = iPermission & arrPermission[OWNER];
} else if (isGroup(userName, strownerGroupName)) {
lastPermission = iPermission & arrPermission[GROUP];
} else {
lastPermission = iPermission & arrPermission[GUEST];
}
if (lastPermission == iPermission)
return 1;
else
return 0;
}
return 0;
}
private static boolean isGroup(String struserName, String strownerGroupName) {
for (String tempGroupName : userList.get(struserName)) {
if (tempGroupName.equals(strownerGroupName)) {
return true;
}
}
return false;
}
}
<문제 Issue>
(1) UserName이 GroupName도 될 수 있다. GroupName이 있어도 UserName은 GroupName이 된다.
입력이 a b,c,d 인 경우 User a가 속한 그룹은 b,c,d가 아니라 a,b,c,d 이다.
<중요 정리>
(1) HashMap과 HashSet 사용
HashMap<String, String> 이런식으로도 쓸 수 있지만 HashMap<String, HashSet<>> 이런식으로도 사용 가능 하다.
(2) 파일 권한 비교 비트연산
'Pro감옥' 카테고리의 다른 글
BOJ5052 전화번호 목록 (4) | 2022.10.06 |
---|---|
BOJ1202 보석도둑 (0) | 2022.09.29 |
[자료구조] 힙(heap) (10) | 2021.04.29 |