Skip to content

Commit 11434ea

Browse files
authored
[20250818] B형 / SWEA / OTT / 이강현
1 parent 2238315 commit 11434ea

File tree

1 file changed

+205
-0
lines changed

1 file changed

+205
-0
lines changed

lkhyun/202508/18 B형 SWEA OTT.md

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
```java
2+
import java.util.*;
3+
4+
class UserSolution
5+
{
6+
static class Movie {
7+
int id;
8+
int genre;
9+
int totalScore;
10+
int insertOrder;
11+
12+
Movie(int id, int genre, int totalScore, int insertOrder) {
13+
this.id = id;
14+
this.genre = genre;
15+
this.totalScore = totalScore;
16+
this.insertOrder = insertOrder;
17+
}
18+
}
19+
20+
static class MovieKey implements Comparable<MovieKey> {
21+
int totalScore;
22+
int insertOrder;
23+
24+
MovieKey(int totalScore, int insertOrder) {
25+
this.totalScore = totalScore;
26+
this.insertOrder = insertOrder;
27+
}
28+
29+
@Override
30+
public int compareTo(MovieKey other) {
31+
// 총점이 높은 순, 같으면 최신 등록순
32+
if (this.totalScore != other.totalScore) {
33+
return Integer.compare(other.totalScore, this.totalScore);
34+
}
35+
return Integer.compare(other.insertOrder, this.insertOrder);
36+
}
37+
}
38+
39+
static class WatchedMovie implements Comparable<WatchedMovie> {
40+
int movieId;
41+
int rating;
42+
int watchOrder;
43+
44+
WatchedMovie(int movieId, int rating, int watchOrder) {
45+
this.movieId = movieId;
46+
this.rating = rating;
47+
this.watchOrder = watchOrder;
48+
}
49+
50+
@Override
51+
public int compareTo(WatchedMovie other) {
52+
// 사용자가 준 평점이 높은 순, 같으면 최근 시청순
53+
if (this.rating != other.rating) {
54+
return Integer.compare(other.rating, this.rating);
55+
}
56+
return Integer.compare(other.watchOrder, this.watchOrder);
57+
}
58+
}
59+
60+
static Map<Integer, Movie> allMovies; // 모든 영화 정보
61+
static TreeMap<MovieKey, Integer> moviesByScore; // 총점 기준 정렬된 영화들
62+
static Map<Integer, TreeMap<MovieKey, Integer>> moviesByGenre; // 장르별 영화들
63+
static Map<Integer, List<WatchedMovie>> userWatchHistory; // 사용자별 시청 기록 (시청 순서)
64+
static Map<Integer, Set<Integer>> userWatchedMovies; // 사용자가 본 영화 ID들
65+
66+
static int movieInsertOrder;
67+
static int watchOrder;
68+
69+
void init(int N) {
70+
allMovies = new HashMap<>();
71+
moviesByScore = new TreeMap<>();
72+
moviesByGenre = new HashMap<>();
73+
userWatchHistory = new HashMap<>();
74+
userWatchedMovies = new HashMap<>();
75+
76+
movieInsertOrder = 0;
77+
watchOrder = 0;
78+
79+
//초기화
80+
for (int i = 1; i <= N; i++) {
81+
userWatchHistory.put(i, new ArrayList<>());
82+
userWatchedMovies.put(i, new HashSet<>());
83+
}
84+
}
85+
86+
int add(int mID, int mGenre, int mTotal) {
87+
if (allMovies.containsKey(mID)) {
88+
return 0; // 이미 존재
89+
}
90+
91+
Movie movie = new Movie(mID, mGenre, mTotal, movieInsertOrder++);
92+
allMovies.put(mID, movie);
93+
94+
MovieKey key = new MovieKey(mTotal, movie.insertOrder);
95+
moviesByScore.put(key, mID);
96+
97+
moviesByGenre.computeIfAbsent(mGenre, k -> new TreeMap<>()).put(key, mID);
98+
99+
return 1;
100+
}
101+
102+
int erase(int mID) {
103+
Movie movie = allMovies.get(mID);
104+
if (movie == null) {
105+
return 0; // 존재x
106+
}
107+
108+
// 전체 영화 목록에서 제거
109+
MovieKey key = new MovieKey(movie.totalScore, movie.insertOrder);
110+
moviesByScore.remove(key);
111+
moviesByGenre.get(movie.genre).remove(key);
112+
allMovies.remove(mID);
113+
114+
// 모든 사용자의 시청 기록에서 제거
115+
for (List<WatchedMovie> watchHistory : userWatchHistory.values()) {
116+
watchHistory.removeIf(watched -> watched.movieId == mID);
117+
}
118+
for (Set<Integer> watchedSet : userWatchedMovies.values()) {
119+
watchedSet.remove(mID);
120+
}
121+
122+
return 1;
123+
}
124+
125+
int watch(int uID, int mID, int mRating) {
126+
Movie movie = allMovies.get(mID);
127+
if (movie == null) {
128+
return 0; // 존재x
129+
}
130+
131+
if (userWatchedMovies.get(uID).contains(mID)) {
132+
return 0; // 이미 시청
133+
}
134+
135+
// 영화 총점 업데이트
136+
MovieKey oldKey = new MovieKey(movie.totalScore, movie.insertOrder);
137+
moviesByScore.remove(oldKey);
138+
moviesByGenre.get(movie.genre).remove(oldKey);
139+
140+
movie.totalScore += mRating;
141+
142+
MovieKey newKey = new MovieKey(movie.totalScore, movie.insertOrder);
143+
moviesByScore.put(newKey, mID);
144+
moviesByGenre.get(movie.genre).put(newKey, mID);
145+
146+
// 사용자 시청 기록 추가
147+
userWatchHistory.get(uID).add(new WatchedMovie(mID, mRating, watchOrder++));
148+
userWatchedMovies.get(uID).add(mID);
149+
150+
return 1;
151+
}
152+
153+
Solution.RESULT suggest(int uID) {
154+
Solution.RESULT result = new Solution.RESULT();
155+
result.cnt = 0;
156+
157+
List<WatchedMovie> watchHistory = userWatchHistory.get(uID);
158+
Set<Integer> watchedMovies = userWatchedMovies.get(uID);
159+
160+
int targetGenre = -1;
161+
162+
if (!watchHistory.isEmpty()) {
163+
// 최근 5개 영화
164+
List<WatchedMovie> recentMovies = new ArrayList<>();
165+
for (int i = Math.max(0, watchHistory.size() - 5); i < watchHistory.size(); i++) {
166+
recentMovies.add(watchHistory.get(i));
167+
}
168+
169+
// 최근 5개를 정렬
170+
recentMovies.sort((a, b) -> {
171+
if (a.rating != b.rating) {
172+
return Integer.compare(b.rating, a.rating); // 평점 높은순
173+
}
174+
return Integer.compare(b.watchOrder, a.watchOrder); // 최근순
175+
});
176+
177+
// 가장 높은 평점
178+
WatchedMovie bestMovie = recentMovies.get(0);
179+
Movie movie = allMovies.get(bestMovie.movieId);
180+
if (movie != null) {
181+
targetGenre = movie.genre;
182+
}
183+
}
184+
185+
// 추천할 영화들
186+
TreeMap<MovieKey, Integer> candidateMovies;
187+
if (targetGenre == -1) {
188+
// 시청 기록이 없음
189+
candidateMovies = moviesByScore;
190+
} else {
191+
candidateMovies = moviesByGenre.getOrDefault(targetGenre, new TreeMap<>());
192+
}
193+
194+
// 이미 시청한 영화 제외하고 추천
195+
for (int movieId : candidateMovies.values()) {
196+
if (!watchedMovies.contains(movieId)) {
197+
result.IDs[result.cnt++] = movieId;
198+
if (result.cnt == 5) break;
199+
}
200+
}
201+
202+
return result;
203+
}
204+
}
205+
```

0 commit comments

Comments
 (0)