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

 

12837번: 가계부 (Hard)

살아있는 화석이라고 불리는 월곡이는 돈에 찌들려 살아가고 있다. 그에게 있어 수입과 지출을 관리하는 것은 굉장히 중요한 문제이다. 스마트폰에 가계부 어플리케이션을 설치해서 사용하려

www.acmicpc.net

쉽네요 ~ 세그먼트 트리 문제

시간 초과되는 부분만 조심해주면 됩니다.

package test01;
import java.util.*;
import java.io.*;
import java.lang.*;
import java.io.*;
public class Main {
	
	public static long tree[];
	
	public static long buildTree(int start, int end , int node , long arr[]) {
		
		if(start==end) {
			return tree[node]=arr[start];
		}
		
		int mid=(start+end)/2;
		
		return tree[node]=buildTree(start,mid,node*2 ,arr)+ buildTree(mid+1,end,node*2+1,arr) ;
		
	}
	public static long select(int start, int end , int node, long left, long right) {
		 if (start > right || end < left) {
	            return 0;
	        }
	        if (start >= left && end <= right) {
	            return tree[node];
	        }
		
		int mid=(start+end)/2;
		
		return   select(start,mid,node*2 ,left, right)+ select(mid+1,end,node*2+1 ,left, right) ;
	}
	
	public static void update(int start, int end , int node, long newValue,long findIndex) {
		   if (start > findIndex || end < findIndex) {
	            return;
	        }
	        if (start == end) {
	            tree[node] += newValue;
	            return;
	        }
			int mid=(start+end)/2;
			
		
			update(start,mid,node*2 ,newValue, findIndex);
			update(mid+1,end,node*2+1 ,newValue, findIndex);
			tree[node]= tree[node*2] + tree[node*2+1];
		
	}
	
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = new StringTokenizer(br.readLine());
        StringBuilder bz= new StringBuilder();
        int n = Integer.parseInt(st.nextToken());
        long arr[] = new long[n];
        tree = new long[n * 4];

        int m = Integer.parseInt(st.nextToken());
      
        for (int i = 0; i < m; i++) {
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken());
            long b = Long.parseLong(st.nextToken());
            long c = Long.parseLong(st.nextToken());
            if (a == 1) {
                update(0, n - 1, 1, c, b - 1);
            } else {
                long mins = select(0, n - 1, 1, Math.min(b, c) - 1, Math.max(b, c) - 1);
               
                System.out.println(mins);
            }
        }
	}
}

'알고리즘 공부' 카테고리의 다른 글

백준 수열과 쿼리 37  (2) 2024.07.15
백준 커피숍2  (0) 2024.04.17
백준 쵯소값과 최댓값  (0) 2024.04.08
백준 구간 합 구하기  (0) 2024.04.04
백준 - 감시  (0) 2024.04.04

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

 

2357번: 최솟값과 최댓값

N(1 ≤ N ≤ 100,000)개의 정수들이 있을 때, a번째 정수부터 b번째 정수까지 중에서 제일 작은 정수, 또는 제일 큰 정수를 찾는 것은 어려운 일이 아니다. 하지만 이와 같은 a, b의 쌍이 M(1 ≤ M ≤ 100

www.acmicpc.net

세그먼트 트리 알고리즘 기본 문제 중 하나입니다.

import java.util.*;
import java.io.*;
public class Main {

	public static long mintree[];
	public static long maxtree[];



	public static long minselect(int start,int end,int node,long left,long right){
		if(end<left||start>right){
			return Long.MAX_VALUE;
		}
		if(right>= end && left <= start){//5>=4 && 1<=0

			return mintree[node];
		}
		int mid=(start+end)/2;
		return Math.min( minselect(start,mid,node*2,left,right), minselect(mid+1,end,node*2+1,left,right));
	}

	public static long MinbuildingTree(int start,int end, int node, long arr[]){
		if(start==end){
			return mintree[node]=arr[start];
		}
		int mid=(start+end)/2;


		return mintree[node]=Math.min(MinbuildingTree(start,mid,node*2,arr), MinbuildingTree(mid+1,end,node*2+1,arr) );
	}

	public static long MaxbuildingTree(int start,int end, int node, long arr[]){
		if(start==end){
			return maxtree[node]=arr[start];
		}
		int mid=(start+end)/2;
		return maxtree[node]=Math.max(MaxbuildingTree(start,mid,node*2,arr), MaxbuildingTree(mid+1,end,node*2+1,arr) );
	}

	public static long maxselect(int start,int end,int node,long left,long right){
		if(end<left||start>right){
			return 0;
		}
		if(right>= end && left <= start){//5>=4 && 1<=0

			return maxtree[node];
		}
		int mid=(start+end)/2;
		return Math.max( maxselect(start,mid,node*2,left,right), maxselect(mid+1,end,node*2+1,left,right));
	}


	public static void main(String[] args) throws Exception {
		Scanner scan = new Scanner(System.in);
		int n=scan.nextInt();
		int m=scan.nextInt();
		long arr[]=new long[n];
		mintree=new long[n*4];
		maxtree=new long[n*4];
		for(int i=0;i<n;i++){
			long tmp=scan.nextLong();
			arr[i]=	tmp;
		}
		
		MinbuildingTree(0,n-1,1,arr);
		MaxbuildingTree(0,n-1,1,arr);

		for(int i=0;i<m;i++){
			long left=scan.nextLong()-1;
			long right=scan.nextLong()-1;
			long mins=minselect(0,n-1,1,left,right);
			long maxs=maxselect(0,n-1,1,left,right);
			System.out.println(mins+" "+maxs);
		

		}
	}
}

'알고리즘 공부' 카테고리의 다른 글

백준 커피숍2  (0) 2024.04.17
백준 가계부  (0) 2024.04.10
백준 구간 합 구하기  (0) 2024.04.04
백준 - 감시  (0) 2024.04.04
백준 배열과 연산  (0) 2024.04.04

아 ㅋㅋ 겨우 골드1 찍엇네요... 후 목표 플레5까지 이제 한걸음 남았네요. ㅎㅎ 
상당히 오래걸렸고 특히나 구현문제들이 난이도가 골드 3~4 수준 넘어가면 기본 3일 이상 걸리는 문제들도 많았습니다.(정말 길면 일주일 넘는것도 ㅜㅜ)
ㅠㅠ 
이제 좀 속도가 붙어서 문제만 잘 이해하면 생각보다 한 1~2시간 걸리는것같고 늦어지면 하루 이틀은 ... 걸리네요 ㅎㅎ 

 
 
 
지난번과 다르게 구현쪽이 상당히 많이 올라갔습니다.
이젠 자료구조나 그리드도 좀 슬슬 올라가고 있고요. ㅎㅎ 뿌듯하네요. 그래도 갈수록 프로그램짤때 메모리나 시간복잡도에 대해서 생각하면서 짜는것같네요 ㅎㅎ 

 
 
후.. 이제 플레가 얼마 안남은것 같다고 느껴지네요 ㅎ ㅎ 

 
 

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

2042번: 구간 합 구하기

첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)과 M(1 ≤ M ≤ 10,000), K(1 ≤ K ≤ 10,000) 가 주어진다. M은 수의 변경이 일어나는 횟수이고, K는 구간의 합을 구하는 횟수이다. 그리고 둘째 줄부터 N+1번째 줄

www.acmicpc.net

세그먼트 트리 알고리즘 기본 문제

import java.util.*;
import java.io.*;
public class Main {
	public static int n;
	public static int m;
	public static int k;
	public static long tree[];
	public static void initTree(long arr[]){
		builingTree(0,n-1,1,arr);
	}

	public static long builingTree(int start ,int end, int node, long arr[]){
		//System.out.println("node:"+node+",start:"+start+",end:"+end);
		if(start==end){
			return tree[node]=arr[start];
		}

		int mid=(start+end)/2; // 0+5 =2

		return tree[node]=builingTree(start, mid,node*2,arr)+builingTree(mid+1,end,node*2+1,arr);
	}

	public static void updateTree(int start,int end,int node,long newValue, long findIndex){
		//System.out.println("node:"+node+",start:"+start+",end:"+end);
		if(findIndex<start||findIndex>end){
			return;
		}

		if(start==end){
			tree[node]=newValue;
			return;
		}

		int mid=(start+end)/2;

		updateTree(start,mid,node*2,newValue,findIndex);
		updateTree(mid+1,end,node*2+1,newValue,findIndex);
		tree[node]=tree[node*2]+tree[node*2+1];
	}

	public static long select (int start,int end,int node,long left,long right){
		//System.out.println("node:"+node+",start:"+start+",end:"+end);
		//System.out.println("left:"+left+",right:"+right);
		if(left>end||right<start){
			//System.out.println("zero");
			return 0;
		}

		if(left<=start&&end<=right){
			//System.out.println("sum:");
			return tree[node];
		}

		int mid=(start+end)/2;

		return select(start,mid,node*2,left,right)+select(mid+1,end,node*2+1,left,right);
	}

	public static void main(String[] args) throws Exception {
		Scanner scan = new Scanner(System.in);
		 n =scan.nextInt();
		 m=scan.nextInt();//change
		 k=scan.nextInt();//sum ?
		int ending=n+m+k+1;
		long arr[]=new long[n];
		for(int t=0;t<n;t++){
			long tmp=scan.nextLong();
			arr[t]=tmp;
		}
		tree=new long[n*4];
		builingTree(0,n-1,1,arr);
		//System.out.println();
		//for(int i=0;i<tree.length;i++){
		//	System.out.print(tree[i]+",");
		//}
		//System.out.println();
		//int query=select(0,n-1,1,0,1);
		//System.out.println("query:"+query);


		for(int t=0;t<(k+m);t++){
			int a=scan.nextInt();
			long b=scan.nextLong();
			long c=scan.nextLong();
			if(a==1){
				//update
				updateTree(0,n-1,1,c, b-1);
				//System.out.println();
				//for(int i=0;i<tree.length;i++){
					//System.out.print(tree[i]+",");
				//}
				//System.out.println();
			}else if(a==2){
				//select
				//b ~ c
				long query=select(0,n-1,1,b-1,c-1);
				System.out.println(query);
			}
		}

		// N+M+K+1 5 +2 +2 +1
		//a, b, c
		//a 1 -> (b->c)
		//a 2->(b~c sum)


	}
}

'알고리즘 공부' 카테고리의 다른 글

백준 가계부  (0) 2024.04.10
백준 쵯소값과 최댓값  (0) 2024.04.08
백준 - 감시  (0) 2024.04.04
백준 배열과 연산  (0) 2024.04.04
백준 마법사 상어와 파이어스톰  (1) 2024.04.03

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

 

15683번: 감시

스타트링크의 사무실은 1×1크기의 정사각형으로 나누어져 있는 N×M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는 5가지 종류가 있다. 각 CCTV가 감

www.acmicpc.net

음 어렵네요 개인적으로는 골3정도? 난이도네요

키포인트는 카메라들을 전부 모아서 방향으로 볼때의 경우의수를 전부 구해주면 해결은 됩니다.

1번 카메라 4방향, 2번 카메라 4방향 ... 5번 카메라 4방향의 모든 경우의수를 따져주면 해결됩니다.

사각지대는 카메라가 못본곳이라고 생각하면됩니다.

import java.util.*;
import java.io.*;
import java.lang.*;
import java.io.*;
public class Main {
	public static int maps[][];
	
	public static boolean bCheck[][];
	public static boolean bdir[];
	public static int n;
	public static int m;
	public static ArrayList<Camera>cameras=new ArrayList<>();
	public static class Camera{
		public int i;
		public int j;
		public int kind;
		public int dir=0;
		public Camera(int i,int j, int kind,int dir) {
			this.i=i;
			this.j=j;
			this.kind=kind;
			this.dir=dir;
		}
	}
	public static ArrayList<Integer>save=new ArrayList<>();
	
	
	
	
	public static void cameraSee(int ci,int cj,int dir) {
		dir=dir%4;
		switch(dir) {
			case 0:
				//n
				for(int i=0;i<n;i++) {
					ci=ci-1;
					if(ci < 0) {
						break;
					}
					
					if(bCheck[ci][cj]==true) {
						break;
					}
					if(maps[ci][cj]!=0) {
						continue;
					}
					maps[ci][cj]=9;
				}
				break;
			case 1:
				//e
				
				for(int i=0;i<m;i++) {
					cj=cj+1;
					
					if(cj > m -1) {
						break;
					}
					
					if(bCheck[ci][cj]==true) {
						break;
					}
					if(maps[ci][cj]!=0) {
						continue;
					}
					maps[ci][cj]=9;
				}
				break;
			case 2:
				//s
				for(int i=0;i<n;i++) {
					ci=ci+1;
					
					if(ci > n-1) {
						break;
					}
					
					if(bCheck[ci][cj]==true) {
						break;
					}
					if(maps[ci][cj]!=0) {
						continue;
					}
					maps[ci][cj]=9;
				}
				break;
			case 3:
				//w
				for(int i=0;i<m;i++) {
					cj=cj-1;
					if(cj < 0 ) {
						break;
					}
					
					if(bCheck[ci][cj]==true) {
						break;
					}
					if(maps[ci][cj]!=0) {
						continue;
					}
					maps[ci][cj]=9;
				}
				
				break;
				default:
					break;
		}
		
		
		
	}
	public static void Prints() {
		System.out.println();
		for(int i=0;i<n;i++) {
			for(int j=0;j<m;j++) {
				
				System.out.print(maps[i][j]);
			}
			System.out.println();
		}
		System.out.println();
	}
	public static int mins=-1;
	public static void backtracking(int cnt) {
		
		if(cnt>=cameras.size()) {
			//Prints();
			int sum=0;
			for(int i=0;i<n;i++) {
				for(int j=0;j<m;j++) {
					if(maps[i][j]==0) {
						sum++;
					}
				}	
			}
			
			if(mins==-1) {
				mins=sum;
			}else {
				mins=Math.min(sum,mins);
			}
			
			//System.out.println("find");
			return;
		}
		
		int initmaps[][] =new int[n][m];
		//System.out.println(cnt);
		//System.out.println(cameras.size());
		
		int ci=cameras.get(cnt).i;
		int cj=cameras.get(cnt).j;
		
		for(int d=0;d<4;d++) {
			
			for(int i=0;i<n;i++) {
				for(int j=0;j<m;j++) {
					initmaps[i][j]=maps[i][j];
				}
			}
			
			int kind=cameras.get(cnt).kind;
			
			switch(kind) {
			//camera kinds
				case 1:
				//	System.out.println(ci+","+cj+","+d);
					cameraSee(ci,cj,d);
					break;
				case 2:
					cameraSee(ci,cj,d);
					cameraSee(ci,cj,d+2);
					break;
				case 3:
					cameraSee(ci,cj,d);
					cameraSee(ci,cj,d+1);
					break;
				case 4:
					cameraSee(ci,cj,d);
					
					cameraSee(ci,cj,d+1);
					cameraSee(ci,cj,d+3);
					break;
				case 5:
					cameraSee(ci,cj,d);
					cameraSee(ci,cj,d+1);
					cameraSee(ci,cj,d+2);
					cameraSee(ci,cj,d+3);
					break;
				default:
					break;
			}
			
			backtracking(cnt+1);
			
			
			for(int i=0;i<n;i++) {
				for(int j=0;j<m;j++) {
					maps[i][j]=initmaps[i][j];
				}
			}
			
		}
	}
	public static void main(String[] args) throws Exception {
		Scanner scan = new Scanner(System.in);
		n =scan.nextInt();
		m =scan.nextInt();
		
		maps=new int[n][m];
		bCheck=new boolean[n][m];
		bdir=new boolean[4];
		for(int i=0;i<n;i++) {
			for(int j=0;j<m;j++) {
				int tmp=scan.nextInt();
				
				maps[i][j]=tmp;
				
				if(tmp==6) {
					bCheck[i][j]=true;
				}
				if(tmp!=0) {
					
					if(tmp!=6) {
						cameras.add(new Camera(i,j,tmp,-1));
					}
				}
			}
		}
		backtracking(0);
		
		System.out.println(mins);
		
		
		

	}
}

'알고리즘 공부' 카테고리의 다른 글

백준 쵯소값과 최댓값  (0) 2024.04.08
백준 구간 합 구하기  (0) 2024.04.04
백준 배열과 연산  (0) 2024.04.04
백준 마법사 상어와 파이어스톰  (1) 2024.04.03
백준 마법사 상어와 토네이도  (0) 2024.04.02

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

 

17140번: 이차원 배열과 연산

첫째 줄에 r, c, k가 주어진다. (1 ≤ r, c, k ≤ 100) 둘째 줄부터 3개의 줄에 배열 A에 들어있는 수가 주어진다. 배열 A에 들어있는 수는 100보다 작거나 같은 자연수이다.

www.acmicpc.net

골드 4치곤 제법 쉬웠던 문제네요

import java.util.*;
import java.io.*;
public class Main {
	public static int matrix[][];
	public static int copyMatrix[][];
	public static int r;
	public static int c;
	public static int n;
	public static int m;
	public static int k;

	public static class Data{
		public int index;
		public int cnt;
		public Data(int index,int cnt){
			this.index=index;
			this.cnt=cnt;
		}
	}
	public static boolean Checking(int [][]matrix,int cnt){
		for(int i=0;i<matrix.length;i++){
			for(int j=0;j<matrix[i].length;j++){
				if(r==i&&c==j){
					if(matrix[r][c]==k){
						//System.out.println();
						System.out.println(cnt);
						return true;
					}
				}
			}
		}
		return false;
	}
	public static void PrintMatrix(int [][]matrix){
		System.out.println();
		for(int i=0;i<matrix.length;i++){
			for(int j=0;j<matrix[i].length;j++){
				System.out.print(matrix[i][j]+",");
			}
			System.out.println();
		}
		System.out.println();
	}
	public static void PrintData(ArrayList<Data>datas){
		for(int i=0;i<datas.size();i++){
			System.out.print("["+datas.get(i).index+","+datas.get(i).cnt+"]"+",");
		}
		System.out.println();

	}
	public static ArrayList<Data> Sorting(ArrayList<Data>datas){
		Collections.sort(datas,  new Comparator<Data>() {
			@Override
			public int compare(Data d1, Data d2) {
				if(d1.cnt>d2.cnt){
					return 1;
				}else if(d1.cnt==d2.cnt){
					if(d1.index>d2.index){
						return 1;
					}else{
						return -1;
					}

				}else if(d1.cnt < d2.cnt){
					return -1;
				}
				return 0;
			}
		});

		return datas;
	}

	public static boolean MakeMatrix(ArrayList<ArrayList<Integer>>gdatas , boolean bRow ,int cnts){
		int imaxs=0;
		int jmaxs=0;
		for(int i=0;i<gdatas.size();i++){
			imaxs=Math.max(gdatas.size(),imaxs);
			for(int j=0;j<gdatas.get(i).size();j++){
				jmaxs=Math.max(gdatas.get(i).size(),jmaxs);
			}

		}
	//	System.out.println("imaxs:"+imaxs+","+"jmaxs"+jmaxs); //3 6

		if(bRow==true){
			matrix=new int[imaxs][jmaxs];
			n=imaxs;
			m=jmaxs;
		}else{
			matrix=new int[jmaxs][imaxs];
			n=jmaxs;
			m=imaxs;
		}

		for(int i=0;i<gdatas.size();i++){
			for(int j=0;j<gdatas.get(i).size();j++){
				//0 0  0 0
				//1 0  0 1
				// 2 0  0 2
				if(bRow==true){
					matrix[i][j]=gdatas.get(i).get(j);
				}else{
					matrix[j][i]=gdatas.get(i).get(j);
				}

			}
		}
		// PrintMatrix(matrix);
		 return Checking(matrix,cnts);
	}

	public static boolean RowCalculate(boolean bRow,int cnts){
		//row sort
		//System.out.println();
		ArrayList<ArrayList<Integer>>gdatas=new ArrayList<>();
		//System.out.println(n+","+m);
		for(int i=0;i<n;i++){
			ArrayList<Data>datas=new ArrayList<>();

			for(int j=0;j<m;j++){
				int tmp=matrix[i][j];
				boolean bCheck=false;

				for(int s=0;s<datas.size();s++){
					if(datas.get(s).index==tmp&&tmp!=0){
						bCheck=true;
						int tmpcnt=datas.get(s).cnt;
						datas.get(s).cnt=tmpcnt+1;
						break;
					}

				}
				if(bCheck==false&&tmp!=0){
					datas.add(new Data(tmp,1));
				}

			}


			//sorting
			//ArrayList<Data> tmpdatas=new ArrayList<>();
			Sorting(datas);
			//makematrix
			//PrintData(datas);

			ArrayList<Integer>tmpDatas=new ArrayList<>();

			for(int s=0;s<datas.size();s++){

				tmpDatas.add(datas.get(s).index);
				tmpDatas.add(datas.get(s).cnt);
			}
			gdatas.add(tmpDatas);

			//System.out.println();
		}

		return 	MakeMatrix(gdatas,bRow,cnts);

	}
	public static boolean ColumCalculate(boolean bRow,int cnts){
		//row sort

		ArrayList<ArrayList<Integer>>gdatas=new ArrayList<>();

		for(int i=0;i<m;i++){
			ArrayList<Data>datas=new ArrayList<>();

			for(int j=0;j<n;j++){
				int tmp=matrix[j][i];
				boolean bCheck=false;

				for(int s=0;s<datas.size();s++){
					if(datas.get(s).index==tmp&&tmp!=0){
						bCheck=true;
						int tmpcnt=datas.get(s).cnt;
						datas.get(s).cnt=tmpcnt+1;
						break;
					}

				}
				if(bCheck==false&&tmp!=0){
					datas.add(new Data(tmp,1));
				}

			}


			//sorting
			//ArrayList<Data> tmpdatas=new ArrayList<>();
			Sorting(datas);
			//makematrix
			//PrintData(datas);

			ArrayList<Integer>tmpDatas=new ArrayList<>();

			for(int s=0;s<datas.size();s++){

				tmpDatas.add(datas.get(s).index);
				tmpDatas.add(datas.get(s).cnt);
			}
			gdatas.add(tmpDatas);

			//System.out.println();
		}

		return MakeMatrix(gdatas,bRow,cnts);

	}

	public static void main(String[] args) throws Exception {
		Scanner scan = new Scanner(System.in);
		 r=scan.nextInt()-1;
		 c=scan.nextInt()-1;
		 k=scan.nextInt(); //anw
		n=3;
		m=3;

		matrix=new int[n][m];
		for(int i=0;i<3;i++){
			for(int j=0;j<3;j++){
				matrix[i][j]=scan.nextInt();
			}
		}

		boolean bCheck= Checking(matrix,0);
		//System.out.println(r+","+c);
		for(int i=1;i<=100;i++){
			if(bCheck==true){

				break;
			}
			if(n>=m){
				//r cal
				bCheck=RowCalculate(true,i);
			}else{
				//c cal
				bCheck=ColumCalculate(false,i);
				//ColumCalculate();
			}
		}
		if(bCheck==false){
			System.out.println(-1);
		}

	}
}

'알고리즘 공부' 카테고리의 다른 글

백준 구간 합 구하기  (0) 2024.04.04
백준 - 감시  (0) 2024.04.04
백준 마법사 상어와 파이어스톰  (1) 2024.04.03
백준 마법사 상어와 토네이도  (0) 2024.04.02
백준 최소 회의실 개수  (0) 2024.04.02

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

20058번: 마법사 상어와 파이어스톰

마법사 상어는 파이어볼과 토네이도를 조합해 파이어스톰을 시전할 수 있다. 오늘은 파이어스톰을 크기가 2N × 2N인 격자로 나누어진 얼음판에서 연습하려고 한다. 위치 (r, c)는 격자의 r행 c

www.acmicpc.net

와 두번다시는 풀고 싶지는 않는문제네요
* 이후 얼음이 있는 칸 3개 또는 그 이상과 인접해있지 않은 칸은 얼음의 양이 1 줄어든다.
->3개 미만은 얼음이 줄어든다 (무슨 국어 문제인가.. ㅎ)
* 남아있는 얼음 중 가장 큰 덩어리가 차지하는 칸의 개수 얼음이 있는 칸이 얼음이 있는 칸과 인접해 있으면, 두 칸을 연결되어 있다고 한다. 덩어리는 연결된 칸의 집합
->연결된 얼음 덩어리들의 칸의 갯수의 합,즉 얼음은 bfs,dfs를 통해서 연결해서 얼음 덩어리들을 계산하라는 의미
 

import java.util.*;
import java.io.*;
import java.lang.*;
import java.io.*;
public class Main {
	public static int n;
	public static int q;
	public static int maps[][];
	public static int copyMaps[][];
	public static boolean bCheck[][];
	public static boolean initbCheck[][];
	public static boolean[][] visited; 
	public static int L;
	public static void prints(int tmpMap[][]){
		System.out.println();
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				System.out.print(tmpMap[i][j]+",");
			}
			System.out.println();
		}
	}
	public static class Ice {
		public int i;
		public int j;
		public Ice(int i,int j) {
			this.i=i;
			this.j=j;
		}
	}
	public static void Rotation(int starti, int startj){
		int cnt=1;
		int rStarti=starti*L;
		int rEndi=starti*L+L;
		int rStartj=startj*L;
		int rEndj=startj*L+L;

		int rLengthI=(rStarti+rEndi)/2;
		int rLengthJ=(rStartj+rEndj)/2;

		int rCountI=(rEndi-rStarti)/2;
		int rCountJ=(rEndi-rStarti)/2;

		//1 ->2
		for(int i=rStarti;i<rLengthI;i++){
			for(int j=rStartj;j<rLengthJ;j++){
				copyMaps[i][j+ rCountJ]=maps[i][j];
			}
		}
		//2->3
		for(int i=rStarti;i<rLengthI;i++){
			for(int j=rLengthJ;j<rEndj;j++){
				copyMaps[i+rCountI][j]=maps[i][j];
			}
		}

		//3->4
		for(int i=rLengthI;i<rEndi;i++){
			for(int j=rLengthJ ;j<rEndj;j++){
				copyMaps[i][j-rCountJ]=maps[i][j];
			}
		}
		//4->1
		for(int i=rLengthI;i<rEndi;i++){
			for(int j=rStartj;j<rLengthJ;j++){

				copyMaps[i-rCountI][j]=maps[i][j];
			}
		}
		//prints(copyMaps);
		
		

	}
	
	public static void Rotations(int starti, int startj) {
	    int rStarti = starti * L;
	    int rStartj = startj * L;
	    int[][] temp = new int[L][L];

	    for (int i = 0; i < L; i++) {
	        for (int j = 0; j < L; j++) {
	            temp[j][L - 1 - i] = maps[rStarti + i][rStartj + j];
	        }
	    }

	    for (int i = 0; i < L; i++) {
	        for (int j = 0; j < L; j++) {
	        	maps[rStarti + i][rStartj + j] = temp[i][j];
	        }
	    }
	}
	public static int bfs(int x, int y) {
	    if(maps[x][y] <= 0) return 0; 
	    int count = 1;
	    Queue<Ice> queue = new LinkedList<>();
	    queue.add(new Ice(x, y));
	    visited[x][y] = true;

	    while (!queue.isEmpty()) {
	        Ice current = queue.poll();
	        int i = current.i;
	        int j = current.j;

	        int[] di = {-1, 1, 0, 0}; 
	        int[] dj = {0, 0, -1, 1}; 

	        for (int k = 0; k < 4; k++) {
	            int ni = i + di[k];
	            int nj = j + dj[k];

	            if (ni >= 0 && ni < n && nj >= 0 && nj < n && !visited[ni][nj] && maps[ni][nj] > 0) {
	                queue.add(new Ice(ni, nj));
	                visited[ni][nj] = true;
	                count++; 
	            }
	        }
	    }
	    return count;
	}
	
	public static void main(String[] args) throws Exception {
		Scanner scan = new Scanner(System.in);
		n=scan.nextInt();
		q=scan.nextInt();
		double tmpn=Math.pow(2,n);
		n=(int)tmpn;
		maps=new int[n][n];
		copyMaps=new int[n][n];
		bCheck=new boolean[n][n];
		initbCheck=new boolean[n][n];
		visited = new boolean[n][n];

		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				maps[i][j]=scan.nextInt();
				copyMaps[i][j]=maps[i][j];
			}
		}
		for(int t=0;t<q;t++){
			
			L=scan.nextInt();

			double tmpL=Math.pow(2,L);
			L=(int)tmpL;
			//2x2
			//4x4
			//8x8
			int divide=n/L;
			
			
			for(int i=0;i<divide;i++){
				for(int j=0;j<divide;j++){
					Rotations(i,j);
				}
			}
			
			int diri[]= {-1,1,0,0};
			int dirj[]= {0,0,-1,1};
			
			ArrayList<Ice> saveIce=new ArrayList<>();
			for (int i = 0; i < n; i++) {
			    for (int j = 0; j < n; j++) {
			        int iceCnt = 0; 
			        for (int k = 0; k < 4; k++) {
			            int ni = i + diri[k];
			            int nj = j + dirj[k];
			            if (ni < 0 || nj < 0 || ni >= n || nj >= n) continue;
			           
			            if (maps[ni][nj] > 0) iceCnt++;
			        }
			        if (iceCnt < 3) {
			            saveIce.add(new Ice(i, j));
			        }
			    }
			}

			// 저장된 모든 칸의 얼음을 1 줄입니다.
			for (Ice ice : saveIce) {
			    maps[ice.i][ice.j] = Math.max(0, maps[ice.i][ice.j] - 1); 
			}
			
		}
		
		int sum=0;
		int maxs=0;
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				if(maps[i][j]>=0) {
					sum+=maps[i][j];
				}
				
			}
		}
		System.out.println(sum);
		int maxSizeOfIce = 0;
for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
        if (!visited[i][j] && maps[i][j] > 0) {
            maxSizeOfIce = Math.max(maxSizeOfIce, bfs(i, j));
        }
    }
}
		System.out.println(maxSizeOfIce);
		//Rotation(0,1);

	}
}

'알고리즘 공부' 카테고리의 다른 글

백준 - 감시  (0) 2024.04.04
백준 배열과 연산  (0) 2024.04.04
백준 마법사 상어와 토네이도  (0) 2024.04.02
백준 최소 회의실 개수  (0) 2024.04.02
백준 배열돌리기2  (0) 2024.04.02

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

 

20057번: 마법사 상어와 토네이도

마법사 상어가 토네이도를 배웠고, 오늘은 토네이도를 크기가 N×N인 격자로 나누어진 모래밭에서 연습하려고 한다. 위치 (r, c)는 격자의 r행 c열을 의미하고, A[r][c]는 (r, c)에 있는 모래의 양을

www.acmicpc.net

골드3 문제인데..ㅋㅋ 두번 다시는 풀고 싶지않는 문제 생각을 좀 해야하네여 ㅎㅎ 

import java.util.*;
import java.io.*;
public class Main {
	public static int n;
	public static int maps[][];
	public static int copyMaps[][];
	public static int ci;
	public static int cj;
	public static int outsand=0;
	public static void Prints(int tmpmaps[][]){
		System.out.println();

		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				System.out.print(tmpmaps[i][j]+",");
			}
			System.out.println();
		}
		System.out.println();
	}
	public static void checking(int checki,int checkj,int input ){
		if(checki> n-1 ||checkj >n-1||checki<0||checkj<0){
			//System.out.println("sendout:"+input);
			outsand=outsand+input;

		}else{
			maps[checki][checkj] = maps[checki][checkj]+input;
		}
	}
	public static void spread(int mci,int mcj,int diri,int dirj,int index ,int pi,int pj){
		//Prints(maps);
		int tmp=maps[mci][mcj];
		maps[mci][mcj]=0;

		int two=  (int)(tmp*0.02);
		int one=  (int)(tmp*0.01);
		int seven=  (int)(tmp*0.07);
		int ten=  (int)(tmp*0.1);
		int five=  (int)(tmp*0.05);
		int alpa=tmp-(two*2+one*2+seven*2+ten*2+five);
		int alpai=mci+diri;
		int alpaj=mcj+dirj;
		/*
		System.out.println("alpa:"+alpa);
		System.out.println("two:"+two);
		System.out.println("seven:"+seven);
		System.out.println("ten:"+ten);
		System.out.println("five:"+five);
		System.out.println("five:"+one);*/
		checking(mci + diri * 2,mcj + dirj * 2, five );
		if(index==0){
			checking(mci+2,mcj, two );
			checking(mci-2,mcj, two );

			checking(alpai-1,alpaj, ten );
			checking(alpai+1,alpaj, ten );

			checking(mci-1,mcj, seven );
			checking(mci+1,mcj, seven );

			checking(pi-1,pj, one );
			checking(pi+1,pj, one );
		}else{
			checking(mci,mcj-2, two );
			checking(mci,mcj+2, two );

			checking(alpai,alpaj-1, ten );
			checking(alpai,alpaj+1, ten );

			checking(mci,mcj-1, seven );
			checking(mci,mcj+1, seven );

			checking(pi,pj-1, one );
			checking(pi,pj+1, one );
		}
		checking(alpai,alpaj, alpa );
		//Prints(maps);
	}
	public static void Rotation(int index){
			if(index%2==1){
				//left 0
				for(int i=0;i<index;i++){
					int tmpi=ci;
					int tmpj=cj;
					ci=ci;
					cj=cj-1;
					if(maps[ci][cj]>0){
						spread(ci,cj,0,-1,0,tmpi,tmpj);
					}
				}
				//copyMaps[][]=maps[ci][cj];
				// down 1
				for(int i=0;i<index;i++){
					int tmpi=ci;
					int tmpj=cj;
					ci=ci+1;
					cj=cj;
					if(maps[ci][cj]>0){
						spread(ci,cj,1,0,1,tmpi,tmpj);
					}
				}
			}else{
				//right 2
				for(int i=0;i<index;i++) {
					int tmpi=ci;
					int tmpj=cj;
					ci = ci;
					cj = cj + 1;
					if(maps[ci][cj]>0){
						spread(ci,cj,0,1,0,tmpi,tmpj);
					}
				}
				// up 3
				for(int i=0;i<index;i++) {
					int tmpi=ci;
					int tmpj=cj;
					ci = ci - 1;
					cj = cj;
					if(maps[ci][cj]>0){
						spread(ci,cj,-1,0,1,tmpi,tmpj);
					}
				}
			}

		//left 1 0
		//down 1 0
		//right 2 1
		//up 2 1
		//..
		//right 6
		//up 6

		//left 6
	}

	public static void main(String[] args) throws Exception {
		Scanner scan = new Scanner(System.in);
		n = scan.nextInt();
		maps=new int[n][n];
		copyMaps=new int[n][n];

		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				int tmp=scan.nextInt();
				maps[i][j]=tmp;
				copyMaps[i][j]=tmp;
			}
		}

		 ci=n/2;
		 cj=n/2;
		//System.out.println("center:"+ci+","+cj);
		for(int i=0;i<n-1;i++) {
			Rotation( i +1 );
		}
		//System.out.println("center:"+ci+","+cj);

		//last left
		for(int i=0;i<n-1;i++){
			int tmpi=ci;
			int tmpj=cj;
			ci=ci;
			cj=cj-1;
			if(maps[ci][cj]>0){
				spread(ci,cj,0,-1,0,tmpi,tmpj);
			}
		}
		//System.out.println("center:"+ci+","+cj);
		System.out.println(outsand);
	}
}

'알고리즘 공부' 카테고리의 다른 글

백준 배열과 연산  (0) 2024.04.04
백준 마법사 상어와 파이어스톰  (1) 2024.04.03
백준 최소 회의실 개수  (0) 2024.04.02
백준 배열돌리기2  (0) 2024.04.02
백준 0 만들기  (1) 2024.04.01

+ Recent posts