250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- java
- 자바 코테
- N과M
- 볼륨 만들기
- 에라토스테네스의채
- 코테
- 알고리즘개념
- 백준2251
- 완전탐색
- 23288
- 중복조합
- 완탐
- 백준
- 중복순열
- D드라이브생성
- 주사위굴리기2
- 순열
- 백준15652
- 정보처리기사
- 알고리즘
- 정올 1620
- 삼성역테
- 백준13458
- 재귀함수
- Bfs와DFS
- 코테준비
- 자바
- 파티션 크기 조정
- BFS
- 전화번호속의암호
Archives
- Today
- Total
뚱땅뚱땅
[문제] 백준 17822번 원판 돌리기 본문
728x90
17822번: 원판 돌리기
반지름이 1, 2, ..., N인 원판이 크기가 작아지는 순으로 바닥에 놓여있고, 원판의 중심은 모두 같다. 원판의 반지름이 i이면, 그 원판을 i번째 원판이라고 한다. 각각의 원판에는 M개의 정수가 적혀
www.acmicpc.net
풀이
왼쪽, 오른쪽 회전만 주의하면! 되는 듯
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class BOJ_17822 {
static int N,M,T;
static int map[][];
static boolean isAdj;
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(in.readLine()," ");
N = Integer.parseInt(st.nextToken()); // 반지름: 1~N
M = Integer.parseInt(st.nextToken()); // 원 하나당 수의 개수: M
T = Integer.parseInt(st.nextToken()); // 회전 회수
map = new int[N+1][M]; //원판 번호 1번부터 N번
for(int i=1;i<=N;i++) {
st = new StringTokenizer(in.readLine(), " ");
for(int j=0;j<M;j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}// init map
for(int i=0;i<T;i++) {
st = new StringTokenizer(in.readLine()," ");
int x = Integer.parseInt(st.nextToken()); // 원 번호 : x 배수
int d = Integer.parseInt(st.nextToken()); // 0: 시계, 1: 반시계
int k = Integer.parseInt(st.nextToken()); // k칸 회전
for(int j=x;j<=N;j+=x) {
for(int a=0;a<k;a++) {
rotate(j,d); // 원판 번호, d 방향
}
}
isAdj = false;
process(); // 인접하면서 같은 수인거 지우기(0으로 표시)
} // instruction
int sum = 0;
for(int i=1;i<=N;i++) {
for(int j=0;j<M;j++) {
if(map[i][j]>0) sum += map[i][j];
}
}
System.out.println(sum);
}
private static void process() {
if(!isLeft()) return; // 남아있는 수 없으면 리턴
boolean[][] visited =new boolean[N+1][M];
int sum = 0, total = 0;
for(int i=1;i<=N;i++) {
for(int j=0;j<M;j++) {
if(!visited[i][j] && map[i][j]>0)
isAdjacent(i, j, visited);
if(map[i][j]>0) {
sum += map[i][j];
total++;
}
}
}
// 인접하면서 같은 수 있다면
if(isAdj) {
// 지우기
for(int i=1;i<=N;i++) {
for(int j=0;j<M;j++) {
if(visited[i][j]) {
map[i][j] = 0;
}
}
}
}
// 인접 & 같은 수 없으면
if(!isAdj) {
// int avg = sum/total;
int avg = sum;
for(int i=1;i<=N;i++) {
for(int j=0;j<M;j++) {
if(map[i][j]==0) continue;
if(map[i][j]*total>avg) {
map[i][j]--;
}else if(map[i][j]*total<avg) {
map[i][j]++;
}
}
}
}
}
static void isAdjacent(int num, int idx, boolean[][] visited) {
int left = (idx+M-1) % M; // 같은 판 왼쪽 수
int right = (idx+1) % M; // 같은 판 오른쪽 수
int down = num-1; // 아래 판
int up = num+1; // 위 판
int standard = map[num][idx]; // 현재 번호(기준점)
if(standard == map[num][left] && !visited[num][left]) {
isAdj =true;
visited[num][left] = true;
isAdjacent(num, left, visited);
}
if(standard == map[num][right] && !visited[num][right]) {
isAdj =true;
visited[num][right] = true;
isAdjacent(num, right, visited);
}
if(down>=1 && down<=N && standard == map[down][idx]&& !visited[down][idx]) {
isAdj =true;
visited[down][idx] = true;
isAdjacent(down, idx, visited);
}
if(up>=1 && up<=N && standard == map[up][idx] && !visited[up][idx]) {
isAdj =true;
visited[up][idx] = true;
isAdjacent(up, idx, visited);
}
}
static boolean isLeft() {
for(int i=1;i<=N;i++) {
for(int j=0;j<M;j++) {
if(map[i][j]>0) return true;
}
}
return false;
}
private static void rotate(int num, int d) {
if(d==0) { // 시계 방향
int tmp = map[num][M-1];
for(int i=M-1;i>0;i--) {
map[num][i] = map[num][i-1];
}
map[num][0] = tmp;
}
else if(d==1) {// 반시계 방향
int tmp = map[num][0];
for(int i=0;i<M-1;i++) {
map[num][i] = map[num][i+1];
}
map[num][M-1] = tmp;
}
}
}
728x90
'알고리즘 > 삼성 SW역량테스트 기출' 카테고리의 다른 글
[문제] 백준 13458번 시험 감독 - 자바 (0) | 2021.08.29 |
---|---|
[문제] 백준 3190번 뱀 (0) | 2021.03.09 |
Comments