백준

[백준] 17822번 원판 돌리기 (java, 시뮬레이션)

해랑쓰 2021. 4. 21. 01:09
728x90
반응형

www.acmicpc.net/problem/17822

 

17822번: 원판 돌리기

반지름이 1, 2, ..., N인 원판이 크기가 작아지는 순으로 바닥에 놓여있고, 원판의 중심은 모두 같다. 원판의 반지름이 i이면, 그 원판을 i번째 원판이라고 한다. 각각의 원판에는 M개의 정수가 적혀

www.acmicpc.net

인접한 영역의 삭제는 큐를 이용해서 해줬다 (쭉 타고 들어가면서 인접한 영역 모두 검사)

시계방향과 반시계를 거꾸로 구현했다 ㅎ d의 조건만 반대로 해주면 된다

평균은 크거나 작은 경우 다른 연산을 하므로 소수점까지 고려해서 실수로 구해줘야 된다.

각 판은 리스트로 구현해서 시계방향, 반시계방향 이동시 앞 뒤의 원소만 빼서 반대 위치에 넣어주면 된다.

 

배수이므로 x로 시작해서 x를 더해가며 판의 번호를 넣어주면 된다. %연산했다가 틀렸다. 2는 4의 배수가 아니지만 2%4==0이여서 돌아가고 있었다.

 

package algo0420;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

class Pos{
	int y,x;

	public Pos(int y, int x) {
		super();
		this.y = y;
		this.x = x;
	}
	
}

public class B_18922_원판돌리기_Main {
	static int n,m,t;
	static ArrayList<Integer>[] pan;
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		
		n=sc.nextInt();
		m=sc.nextInt();
		t=sc.nextInt();
		pan=new ArrayList[n+1];
		for (int i = 1; i <=n; i++) {
			pan[i]=new ArrayList<>();
		}
		for (int i = 1; i <= n; i++) {
			for (int j = 0; j < m; j++) {
				pan[i].add(sc.nextInt());
			}
		}
//		print();
		for (int tc = 0; tc < t; tc++) {
			int x=sc.nextInt();//x의 배수인 번호
			int d=sc.nextInt();//방향 0 시계 1반시계
			int k=sc.nextInt();// k칸 회전 
			
			rotate(x,d,k);
//			print();
			calculate();
//			print();
		}
		int answer=0;
		for (int i = 1; i <=n; i++) {
			for (int j = 0; j < m; j++) {
				int cur=pan[i].get(j);
				answer+=cur;
			}
		}
		System.out.println(answer);
	}
	private static void calculate() {
		boolean[][] vis=new boolean[n+1][m];
		boolean exist=false;
		int total=0;
		int div=0;
		for (int i = 1; i <=n; i++) {
			for (int j = 0; j < m; j++) {
				total+=pan[i].get(j);
				if(pan[i].get(j)!=0) {
					div+=1;
					int cnt=0;
					int cur=pan[i].get(j);//기준 값
					Queue<Pos> q=new LinkedList<Pos>();
					q.add(new Pos(i,j));
					vis[i][j]=true;
					while(q.size()!=0) {
						Pos temp=q.poll();
						int y=temp.y;
						int x=temp.x;
						if(y-1>=1 && pan[y-1].get(x)==cur) {
							cnt+=1;
							pan[y-1].set(x, 0);
							q.add(new Pos(y-1,x));
							vis[y-1][x]=true;
						}
						if(y+1<=n && pan[y+1].get(x)==cur) {
							cnt+=1;
							pan[y+1].set(x, 0);
							q.add(new Pos(y+1,x));
							vis[y+1][x]=true;
						}
						if(pan[y].get((x-1+m)%m)==cur) {
							cnt+=1;
							pan[y].set((x-1+m)%m, 0);
							q.add(new Pos(y,(x-1+m)%m));
							vis[y][(x-1+m)%m]=true;
						}
						if(pan[y].get((x+1)%m)==cur) {
							cnt+=1;
							pan[y].set((x+1)%m, 0);
							q.add(new Pos(y,(x+1)%m));
							vis[y][(x+1)%m]=true;
						}
						if(cnt!=0) {
							pan[y].set(x, 0);
							exist=true;
						}
					}
					
					
				}
			}
		}
		if(!exist) {//인접하는거 없다
//			System.out.println(total+","+div);
			double avg=(double)total/div; //정수, 크거나 작은거 비교
			for (int i = 1; i <=n; i++) {
				for (int j = 0; j < m; j++) {
					int cur=pan[i].get(j);
//					System.out.println(cur+","+avg);
					if(cur>avg) {
						pan[i].set(j, cur-1);
					}else if(cur!=0 & cur<avg){
						pan[i].set(j, cur+1);
					}
				}
			}
		}
	}
	private static void rotate(int x, int d, int k) {
		
		for (int num = x; num <=n; num+=x) {
//			if(num%x==0) {
				if(d==1) {
					clockwise(num,k);//시계방향으로 num원판 k번 회전
				}else {
					rclockwise(num,k);
				}
//			}
		}
	}
	private static void rclockwise(int num, int k) {
		
		for (int i = 0; i < k; i++) {
			int temp=pan[num].get(m-1);
			pan[num].remove(m-1);
			pan[num].add(0,temp);
		}
		
	}
	private static void clockwise(int num, int k) {
//		System.out.println(num);
		for (int i = 0; i < k; i++) {
			int temp=pan[num].get(0);
			pan[num].remove(0);
			pan[num].add(temp);
		}
		
	}
	
	private static void print() {
		for (int i = 1; i <=n; i++) {
			for (int j = 0; j < m; j++) {
				System.out.print(pan[i].get(j)+" ");
			}
			System.out.println();
		}
		System.out.println();
	}
}
728x90
반응형