2470번: 두 용액

첫째 줄에는 전체 용액의 수 N이 입력된다. N은 2 이상 100,000 이하이다. 둘째 줄에는 용액의 특성값을 나타내는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 수들은 모두 -1,000,000,000 이상 1,000,00

www.acmicpc.net

 


 

  • 생각

투 포인터 방식을 사용하면 될 것 같다.

1. 일단 입력 받은 배열을 오름차순 정렬을 통해 왼쪽부터 오른쪽으로 점점 수가 커지게 정렬시킨다.

2. 용액 배열 양쪽에서 다가오면서, 두 개의 합이 0에 가장 가까울 경우 저장해준다.

3. 두 개의 합이 0 보다 작을 경우, 조금 더 0보다 가까운 경우가 있는지 알아보기 위해 왼쪽에서 다가오는 index를 하나 늘려준다.

4. 두 개의 합이 0보다 클 경우, 조금 더 0보다 가까운 경우가 있는지 알아보기 위해 오른쪽에서 다가오는 index를 하나 줄여준다.

 

 

  • 코드

 

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.InputMismatchException;

public class Main {
    static int[] array;
    static int N, answer1, answer2;
	
	public static void main(String[] args) throws Exception {
		SetData();
		TwoPointer();
		System.out.println(answer1 + " " + answer2);
	}

	// 데이터
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);
		
        N = in.nextInt();
		array = new int[N];
		answer1 = answer2 = 0;

		for (int i = 0; i < N; ++i) {
			array[i] = in.nextInt();
		}
		Arrays.sort(array);
	}

	private static void TwoPointer() {
		int min = Integer.MAX_VALUE;
		int left = 0, right = N - 1;
		
		// 투 포인터
		while (left < right) {
			int sum = array[left] + array[right];

			// v가 최소일 때 특성값 갱신
			if (min > Math.abs(sum)) {
				min = Math.abs(sum);
				answer1 = array[left];
				answer2 = array[right];
			}

			if (sum > 0)
				right--;
			else
				left++;
		}
	}
}

class InputReader {

	private final InputStream stream;
	private final byte[] buf = new byte[8192];
	private int curChar, snumChars;

	public InputReader(InputStream st) {
		this.stream = st;
	}

	public int read() {
		if (snumChars == -1)
			throw new InputMismatchException();
		if (curChar >= snumChars) {
			curChar = 0;
			try {
				snumChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (snumChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	public int nextInt() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public long nextLong() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public int[] nextIntArray(int n) {
		int a[] = new int[n];
		for (int i = 0; i < n; i++) {
			a[i] = nextInt();
		}
		return a;
	}

	public String readString() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	}

	public String nextLine() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isEndOfLine(c));
		return res.toString();
	}

	public boolean isSpaceChar(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	private boolean isEndOfLine(int c) {
		return c == '\n' || c == '\r' || c == -1;
	}
}

 

2178번: 미로 탐색

첫째 줄에 두 정수 N, M(2 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 M개의 정수로 미로가 주어진다. 각각의 수들은 붙어서 입력으로 주어진다.

www.acmicpc.net


 

 

  • 생각

bfs 방식을 통해 배열을 돌릴때 배열 값을 +1, check 해주면서 돌리면 될 것 같다.

 

 

  • 코드

 

import java.io.IOException;
import java.io.InputStream;
import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
    static int[][] array;
    static boolean[][] check;
    static int N,M;
    static int[] x = {-1,1,0,0};
    static int[] y = {0,0,-1,1};
	
	public static void main(String[] args) throws Exception {
		SetData();
        bfs();
        System.out.println(array[N-1][M-1]);
	}

	// 데이터
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);
		
        N = in.nextInt();
        M = in.nextInt();
        
        array = new int[N][M];
        check = new boolean[N][M];
        check[0][0] = true;

        for (int i = 0; i < N; i++) {
            String s = in.readString();
            for (int j = 0; j < M; j++) {
                array[i][j] = s.charAt(j) - '0';
            }
        }		
	}

    public static void bfs(){
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[] {0,0});
        
        while(!queue.isEmpty()){
            int location[] = queue.poll();            	

            for(int direction = 0; direction<4; direction++){
                int r = location[0] + x[direction];
                int c = location[1] + y[direction];
                
                if(r >= 0 && c >= 0 && r < N && c < M){
                    if(array[r][c] != 0 && !check[r][c]){
                        queue.offer(new int[] {r,c});
                        check[r][c] = true;
                        array[r][c] = array[location[0]][location[1]] + 1;
                    }
                }
            }
        }
    }
}

class InputReader {

	private final InputStream stream;
	private final byte[] buf = new byte[8192];
	private int curChar, snumChars;

	public InputReader(InputStream st) {
		this.stream = st;
	}

	public int read() {
		if (snumChars == -1)
			throw new InputMismatchException();
		if (curChar >= snumChars) {
			curChar = 0;
			try {
				snumChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (snumChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	public int nextInt() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public long nextLong() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public int[] nextIntArray(int n) {
		int a[] = new int[n];
		for (int i = 0; i < n; i++) {
			a[i] = nextInt();
		}
		return a;
	}

	public String readString() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	}

	public String nextLine() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isEndOfLine(c));
		return res.toString();
	}

	public boolean isSpaceChar(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	private boolean isEndOfLine(int c) {
		return c == '\n' || c == '\r' || c == -1;
	}
}

 

1520번: 내리막 길

여행을 떠난 세준이는 지도를 하나 구하였다. 이 지도는 아래 그림과 같이 직사각형 모양이며 여러 칸으로 나뉘어져 있다. 한 칸은 한 지점을 나타내는데 각 칸에는 그 지점의 높이가 쓰여 있으

www.acmicpc.net

 


 

  • 생각

bfs방식을 통해 배열을 돌리면 될 것 같다.

=> 해당 방식으로만 하면 시간초과가 뜬다.

 

해결방법 : dp배열을 하나 더 만들어서 지나온 길의 값을 저장해 놓는다. 

 

 

  • 코드

실패 코드 : BFS를 통해 queue를 이용하여서 품.  메모리 초과

 

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
	private static int N, M;
	private static int[][] array;
	private static int count;

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		M = Integer.parseInt(st.nextToken());
		N = Integer.parseInt(st.nextToken());
		array = new int[M][N];
		count = 0;
		
		for(int i = 0; i < M; i++) {
			st = new StringTokenizer(br.readLine());
			for(int j = 0 ; j < N; j++)
				array[i][j] = Integer.parseInt(st.nextToken());
		}
		
		bfs();
		System.out.println(count);
	}
	
    private static int[][] xy = {
            {1, 0}, {0, 1},
            {-1, 0}, {0, -1}
    };
	
	private static void bfs() {
        
        Queue<int[]> queue = new LinkedList<>();
        queue.add(new int[] {0,0});
        
        while(!queue.isEmpty()){
            int location[] = queue.poll();

            // 마지막에 도달하면 count++
            if(location[0] == M-1 && location[1] == N-1) {            
            	count++;
            	continue;
            }

            for (int[] direction : xy) {
                int r = location[0] + direction[0];
                int c = location[1] + direction[1];
                
                if(r >= 0 && c >= 0 && r < M && c < N) {
                	// 값이 작아질때만 queue에 추가
                    if(array[location[0]][location[1]] > array[r][c]) {
                        queue.add(new int[] {r,c});
                    }
                }
            }
        }    
    }
}

 

실패 코드2 : queue를 이용하여 돌린 bfs를 재귀형식으로 바꿔줌.   시간 초과

 

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
	private static int N, M;
	private static int[][] array;
	private static int count;

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		M = Integer.parseInt(st.nextToken());
		N = Integer.parseInt(st.nextToken());
		array = new int[M][N];
		count = 0;

		for (int i = 0; i < M; i++) {
			st = new StringTokenizer(br.readLine());
			for (int j = 0; j < N; j++)
				array[i][j] = Integer.parseInt(st.nextToken());
		}

		bfs(0, 0);
		System.out.println(count);
	}

	// 메모리 초과때문에 메모리 줄이기 위함
	private static int[][] xy = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };

	// 메모리 초과 때문에 bfs를 queue에서 재귀로 바꿈
	private static void bfs(int a, int b) {
		// base case
		if (a == M - 1 && b == N - 1) {
			count++;
			return;
		}

		for (int[] direction : xy) {
			int r = a + direction[0];
			int c = b + direction[1];

			if (r >= 0 && c >= 0 && r < M && c < N) {
				// 값이 작아질때만 queue에 추가
				if (array[a][b] > array[r][c]) {
					bfs(r, c);
				}
			}

		}
	}
}

 

성공 코드 : dp배열을 하나 더 만들어서 이미 지나온 길을 가려고 할 시 끝까지 가지않고 전에 저장해 놓은 값을 return 해준다.

 

import java.io.IOException;
import java.io.InputStream;
import java.util.InputMismatchException;

public class Main {
	private static int N, M;
	private static int[][] array, dp;
	
	public static void main(String[] args) throws Exception {
		SetData();
		System.out.println(bfs(0,0));
	}

	// 데이터
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);
		
        M = in.nextInt();
		N = in.nextInt();
		array = new int[M][N];
		dp = new int[M][N];

		for (int i = 0; i < M; i++) {
			for (int j = 0; j < N; j++) {
				array[i][j] = in.nextInt();
				dp[i][j] = -1;
			}
		}
		
	}

	// 메모리 초과때문에 메모리 줄이기 위함
	private static int[][] xy = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };
	
	// 메모리 초과 때문에 bfs를 queue에서 재귀로 바꿈
	private static int bfs(int a, int b) {
		// base case
		if (a == M - 1 && b == N - 1)	return 1;
		// 이미 지나온 길이면 return으로 해당 index의 값을 리턴해준다. 이렇게 함으로써 왔던길을 가지않아도 됌.
		if(dp[a][b] != -1)	 return dp[a][b];
		dp[a][b] = 0;
		
		for (int[] direction : xy) {
			int r = a + direction[0];
			int c = b + direction[1];

			if (r >= 0 && c >= 0 && r < M && c < N) {
				// 작아질 때만 재귀로 들어감
				if (array[a][b] > array[r][c]) {
					// 재귀를 돌면서 해당 index 방향에서 끝까지 도달한 횟수를 누적해서 index에 더 해줌
					dp[a][b] += bfs(r, c);
					
				}
			}
		}
		return dp[a][b];
	}
}

class InputReader {

	private final InputStream stream;
	private final byte[] buf = new byte[8192];
	private int curChar, snumChars;

	public InputReader(InputStream st) {
		this.stream = st;
	}

	public int read() {
		if (snumChars == -1)
			throw new InputMismatchException();
		if (curChar >= snumChars) {
			curChar = 0;
			try {
				snumChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (snumChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	public int nextInt() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public long nextLong() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public int[] nextIntArray(int n) {
		int a[] = new int[n];
		for (int i = 0; i < n; i++) {
			a[i] = nextInt();
		}
		return a;
	}

	public String readString() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	}

	public String nextLine() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isEndOfLine(c));
		return res.toString();
	}

	public boolean isSpaceChar(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	private boolean isEndOfLine(int c) {
		return c == '\n' || c == '\r' || c == -1;
	}
}

 

 

7576번: 토마토

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N이 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M,N ≤ 1,000 이다. 둘째 줄부터는 하나의 상자에 저장된 토마토

www.acmicpc.net

 


 

  • 생각

BFS를 돌리는데 입력받을 때, 1입력받으면 queue에 넣어놓는다. BFS를 돌면서 0을 1로 바꿀 수 있는 곳은 다 바꾼다.

 

 

  • 코드

 

import java.io.IOException;
import java.io.InputStream;
import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
    static int N, M, max;
    static int[][] array;
	static int[] x = { -1, 1, 0, 0 };
	static int[] y = { 0, 0, -1, 1 };
	static Queue<int[]> queue;

	public static void main(String[] args) throws Exception {
		SetData();
        bfs();
        
        if (!check()) {
            System.out.println(-1);
        } else if(max==0){
            System.out.println(max);
        }else{
            System.out.println(max-1);
        }
	}

	// 데이터
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);

		N = in.readInt();		
        M = in.readInt();
        array = new int[M][N];
        max = 0;
        queue = new LinkedList<>();
        for (int i = 0; i < M; i++) {
            for (int j = 0; j < N; j++) {
                int M = in.readInt();
                array[i][j] = M;
                if (M == 1) {
                    queue.offer(new int[]{i, j});
                }
            }
        }
		
	}

    static public void bfs() {
        while (!queue.isEmpty()) {
            int[] location = queue.poll();
            
            for (int direction = 0; direction < 4; direction++) {            	
                int r = location[0] + x[direction];
                int c = location[1] + y[direction];
                
                if (0 > r || r >= M || 0 > c || c >= N) continue;
                
                if (array[r][c] == 0) {
                    array[r][c] = array[location[0]][location[1]] + 1;
                    queue.offer(new int[]{r, c});
                    if (array[r][c] > max) {
                        max = array[r][c];
                    }
                }
                
            }
        }
    }

    static public boolean check() {
        for (int i = 0; i < M; i++) {
            for (int j = 0; j < N; j++) {
                if (array[i][j] == 0) {
                    return false;
                }
            }
        }
        return true;
    }
	
	private static class InputReader {
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public int read() {
			if (numChars == -1) {
				throw new InputMismatchException();
			}
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0) {
					return -1;
				}
			}
			return buf[curChar++];
		}

		public int readInt() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9') {
					throw new InputMismatchException();
				}
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public boolean isSpaceChar(int c) {
			if (filter != null) {
				return filter.isSpaceChar(c);
			}
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}
	}
}

 

1405번: 미친 로봇

첫째 줄에 N, 동쪽으로 이동할 확률, 서쪽으로 이동할 확률, 남쪽으로 이동할 확률, 북쪽으로 이동할 확률이 주어진다. N은 14보다 작거나 같은 자연수이고,  모든 확률은 100보다 작거나 같은 자

www.acmicpc.net


 

  • 생각

조심해야 할 것

1. 동서남북으로 갈 확률이 자연수로 주어지기 때문에 0.01을 곱해 확률로 만들어주기

2. 출력할 때 소수점 10의 자리까지 출력해주기

 

 

푼 방식 (DFS)

1. 한 방향으로 최대 14번 움직일 수 있기 때문에 (15, 15)에서 시작하고 판은 적어도 29*29여야 한다.

2. 한번 움직일 때마다 4방향 다 움직이면서 브루트 포스 알고리즘을 적용하여 답을 탐색한다.

3. N번 움직였을 경우 누적 확률을 더해주면 됩니다.

 

 

  • 코드

 

import java.io.IOException;
import java.io.InputStream;
import java.util.InputMismatchException;

public class Main {
	static int N;
	static double percentage;	
	static double[] percent;	// 각 방향으로 이동할 확률
	static boolean[][] check;	// 단순 경로인지 아닌지 체크
	static int[] x = { -1, 1, 0, 0 };
	static int[] y = { 0, 0, -1, 1 };

	public static void main(String[] args) throws Exception {
		SetData();
		dfs(14, 14, 0, 1.0);
		System.out.println(percentage);
	}

	// 데이터
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);

		percent = new double[4];
		check = new boolean[30][30];
		percentage = 0.0;
		check[14][14] = true;	

		N = in.readInt();		

		// 입력값을 확률로 바꿈
		for (int i = 0; i < 4; i++) 
			percent[i] = in.readInt() * 0.01;
		
	}

	private static void dfs(int a, int b, int count, double per) {
		// basecase
		if (count == N) {
			percentage += per;
			return;
		}

		// 4방향 이동
		for (int i = 0; i < 4; i++) {
			int r = a + x[i];
			int c = b + y[i];
			if (!check[r][c]) {
				check[r][c] = true;
				dfs(r, c, count + 1, per * percent[i]);
				check[r][c] = false;
			}
		}
	}
	
	private static class InputReader {
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public int read() {
			if (numChars == -1) {
				throw new InputMismatchException();
			}
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0) {
					return -1;
				}
			}
			return buf[curChar++];
		}

		public int readInt() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9') {
					throw new InputMismatchException();
				}
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public boolean isSpaceChar(int c) {
			if (filter != null) {
				return filter.isSpaceChar(c);
			}
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}
	}
}

 

 

 

1477번: 휴게소 세우기

첫째 줄에 현재 휴게소의 개수 N, 더 지으려고 하는 휴게소의 개수 M, 고속도로의 길이 L이 주어진다. N은 100보다 작거나 같으며, M도 100보다 작거나 같다. L은 100보다 크거나 같고, 1000보다 작거나

www.acmicpc.net


 

  • 생각

이분 탐색을 이용해서 풀면 간단하게 풀릴 것 같은 문제이다.

 

 

  • 코드

 

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.InputMismatchException;

public class Main {
	static int[] array;
	static int N, M, L, answer;

	public static void main(String[] args) throws Exception {
		SetData();
		BinarySearch(0, L - 1);
		System.out.println(answer);
	}

	// 데이터
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);

		N = in.readInt();
		M = in.readInt();
		L = in.readInt();

		array = new int[N + 2];
		array[N + 1] = L;

		for (int i = 1; i <= N; i++)
			array[i] = in.readInt();
		Arrays.sort(array);
	}

	private static void BinarySearch(int left, int right) {
		while (left <= right) {
			int mid = (left + right) / 2;
			
			if (isPossible(mid)) 
				left = mid + 1;
			else 
				right = mid - 1;			
		}

		answer = left;
	}

	public static boolean isPossible(int mid) {
		int sum = 0;
		for (int i = 0; i < N + 1; i++) {
			sum += (array[i + 1] - array[i] - 1) / mid;
		}
		return M < sum;
	}
	
	private static class InputReader {
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public int read() {
			if (numChars == -1) {
				throw new InputMismatchException();
			}
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0) {
					return -1;
				}
			}
			return buf[curChar++];
		}

		public int readInt() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9') {
					throw new InputMismatchException();
				}
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public boolean isSpaceChar(int c) {
			if (filter != null) {
				return filter.isSpaceChar(c);
			}
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}
	}
}

 

14502번: 연구소

인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크

www.acmicpc.net


 

  • 코드

정답 코드 : 벽을 dfs 알고리즘 방식으로 세우면서 3개를 세울 때 dfs로 안전하지 않은 곳에 바이러스를 퍼뜨린 다음에 안전한 지역의 수를 return 받는다. 받은 return 값의 최대 값을 출력.

 

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
 
public class Main {	
	static int[][] array;
	static int N, M, max = 0;
    static int[] x = {-1, 1, 0, 0};
    static int[] y = {0, 0, -1, 1};
	
	public static void main(String[] args) throws IOException { 
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		
		array = new int[N][M];

		for(int i = 0; i < N; i++) {
			st = new StringTokenizer(br.readLine());
			for(int j = 0; j < M; j++) 
				array[i][j] = Integer.parseInt(st.nextToken());			
		}
		
		dfs(0);
		System.out.println(max);

	}
	
    // 벽 기둥 3개를 세우기 위한 함수
	// DFS 재귀 형식
    private static void dfs(int count) {
    	// base case
        if(count == 3) {
            max = Math.max(max, bfs());
            return;
        }
        
        for(int i = 0; i < N; i++) {
            for(int j = 0 ; j < M; j++) {
                if(array[i][j] == 0) {
                    array[i][j] = 1;
					dfs(count+1);
                    array[i][j] = 0;
                }
            }
        }
    }
	
	private static int bfs() {		
		// 임시 배열 (기존 배열을 유지하기 위함)
        int[][] spreadVirusArray = new int[N][M];
        for(int i = 0; i < N; i++)
            for(int j = 0; j < M; j++)
            	spreadVirusArray[i][j] = array[i][j];
        
        Queue<int[]> queue = new LinkedList<>();
        
        // 바이러스 인 곳을 queue에 위치를 추가해줌.
        for(int i = 0; i < N; i++)
        	for(int j = 0; j < M; j++)
        		if(spreadVirusArray[i][j] == 2) queue.add(new int[] {i,j});
        
        // 벽으로 보호되지 않은 곳은 virus를 퍼뜨림
        // BFS
        while(!queue.isEmpty()){
            int location[] = queue.poll();

            for(int direction = 0; direction < 4; direction++){
                int r = location[0] + x[direction];
                int c = location[1] + y[direction];

                if(r >= 0 && c >= 0 && r < N && c < M) {
                    if(spreadVirusArray[r][c] == 0) {
                    	spreadVirusArray[r][c] = 2;
                        queue.add(new int[] {r,c});
                    }
                }
            }
        }                
        
        // 바이러스가 퍼지지 않은 지역 수
		int count = 0;
		for(int i = 0; i < N; i++) {
			for(int j = 0; j < M; j++)
				if(spreadVirusArray[i][j] == 0) count++;
		}
		
        return count;
    }
}

 

 

현재 까지 메모리, 속도 개선해보려고 노력하고 있는 코드

 

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
 
public class Main {	
	static int[][] array, spreadVirusArray;
	static int N, M, max = 0;
	
	public static void main(String[] args) throws IOException { 
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		
		array = new int[N][M];
		spreadVirusArray = new int[N][M];

		for(int i = 0; i < N; i++) {
			st = new StringTokenizer(br.readLine());
			for(int j = 0; j < M; j++) 
				array[i][j] = Integer.parseInt(st.nextToken());			
		}
		
		dfs(0);
		System.out.println(max);

	}
    
    private static int[][] xy = {
            {1, 0}, {0, 1},
            {-1, 0}, {0, -1}
    };
    
    // 벽 기둥 3개를 세우기 위한 함수
	// DFS 재귀 형식
    private static void dfs(int count) {
    	// base case
        if(count == 3) {
            max = Math.max(max, bfs());
            return;
        }
        
        for(int i = 0; i < N; i++) {
            for(int j = 0 ; j < M; j++) {
                if(array[i][j] == 0) {
                    array[i][j] = 1;
					dfs(count+1);
                    array[i][j] = 0;
                }
            }
        }
    }
	
	private static int bfs() {		
		// 임시 배열 (기존 배열을 유지하기 위함)
        for(int i = 0; i < N; i++)
            for(int j = 0; j < M; j++)
            	spreadVirusArray[i][j] = array[i][j];
        
        Queue<int[]> queue = new LinkedList<>();
        
        // 바이러스 인 곳을 queue에 위치를 추가해줌.
        for(int i = 0; i < N; i++)
        	for(int j = 0; j < M; j++)
        		if(spreadVirusArray[i][j] == 2) queue.add(new int[] {i,j});
        
        // 벽으로 보호되지 않은 곳은 virus를 퍼뜨림
        // BFS
        while(!queue.isEmpty()){
            int location[] = queue.poll();

            for (int[] direction : xy) {
                int r = location[0] + direction[0];
                int c = location[1] + direction[1];

                if(r >= 0 && c >= 0 && r < N && c < M) {
                    if(spreadVirusArray[r][c] == 0) {
                    	spreadVirusArray[r][c] = 2;
                        queue.add(new int[] {r,c});
                    }
                }
            }
        }                
        
        // 바이러스가 퍼지지 않은 지역 수
		int count = 0;
		for(int i = 0; i < N; i++) {
			for(int j = 0; j < M; j++)
				if(spreadVirusArray[i][j] == 0) count++;
		}
		
        return count;
    }
}

 

 

메모리 적게 쓰는 방법

 

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
	static int[][] array;
	static int N, M, answer;
    static int[] x = {-1, 1, 0, 0};
    static int[] y = {0, 0, -1, 1};

	public static void main(String[] args) throws Exception {
		SetData();	
		blockArea();
		System.out.println(answer);
	}

	// 데이터
	private static void SetData() throws Exception  {
		InputReader in = new InputReader(System.in);
		
		N = in.readInt();
		M = in.readInt();		
		array = new int[N][M];
		answer = 0;

		for(int i = 0; i < N; i++) {
			for(int j = 0; j < M; j++) 
				array[i][j] = in.readInt();			
		}
	}
	
	private static void blockArea() {
		int totalArea = N*M;
		
		for (int first = 0; first < totalArea-2; first++) {
			if (array[first/M][first%M]==0) {
				array[first/M][first%M] = 1;
			}else {	continue;}
			
			for (int second = first+1; second < totalArea-1; second++) {
				if (array[second/M][second%M]==0) {
					array[second/M][second%M] = 1;
				}else {	continue;}
				
				for (int third = second+1; third < totalArea; third++) {
					if (array[third/M][third%M]== 0) {
						array[third/M][third%M] = 1;
					}else {	continue;}
					
					updateAnswer();
					
					array[third/M][third%M] = 0;
				}
				array[second/M][second%M] = 0;
			}
			array[first/M][first%M] = 0;
		}
	}
	
	private static void updateAnswer() {
		int result=0;
		
		for (int x = 0; x < N; x++) {
			for (int y = 0; y < M; y++) {
				if(array[x][y] == 2) {
					DFS(x,y);
				}
			}
		}

		
		for (int x = 0; x < N; x++) {
			for (int y = 0; y < M; y++) {
				if (array[x][y]==0) {
					result++;
				}else if (array[x][y] == 3) {
					array[x][y]=0;
				}
			}
		}

		answer = Math.max(answer, result);		
	}
	
	private static void DFS(int a, int b) {
		int r,c;
		for (int i = 0; i < 4; i++) {
			r = a+x[i];
			c = b+y[i];
			
			if(r < 0 || c < 0 || r >= N || c >= M || array[r][c] != 0) continue;

			array[r][c]=3;
			DFS(r,c);
			
		}
	}
    
	private static class InputReader {
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public int read() {
			if (numChars == -1) {
				throw new InputMismatchException();
			}
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0) {
					return -1;
				}
			}
			return buf[curChar++];
		}

		public int readInt() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9') {
					throw new InputMismatchException();
				}
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public boolean isSpaceChar(int c) {
			if (filter != null) {
				return filter.isSpaceChar(c);
			}
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}
	}
}

 

7579번: 앱

입력은 3줄로 이루어져 있다. 첫 줄에는 정수 N과 M이 공백문자로 구분되어 주어지며, 둘째 줄과 셋째 줄에는 각각 N개의 정수가 공백문자로 구분되어 주어진다. 둘째 줄의 N개의 정수는 현재 활

www.acmicpc.net


 

  • 생각

문제를 푼 계기) 무심코 알고리즘 분류를 눌렀다가 배낭문제가 적힌 것을 봐버렸다. 배낭문제 풀 때도 완벽하게 이해하고 풀지 않았던 것 같아서 비슷한 문제를 풀어봐야겠다고 생각했다.

 

1. dfs로 파라미터를 (현재까지 확보된 메모리 용량, 메모리에 따른 비용)을 보내면서 돈다. basecase론 확보된 용량이 원해는 용량보다 클 경우로 둔다.  ==>> 시간초과

 

 

2. dp 배열을 통해 해결하는 방법이 있다. 해결 방법은 해당 메모리를 dp[비용] = 최대 메모리로 채워 넣는 방법이다. 

 

 

  • 코드

정답 코드 : dp 배열을 통해 가장 큰 메모리부터 j-cost인덱스 dp배열에 cost인덱스 에 맞는 메모리를 더 했을때 더 크면 dp배열을 초기화 시키는 방법이다. 이렇게해주면 최종적으로 dp 배열엔 dp[비용] = 최대 메모리가 들어있다.

 

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.InputMismatchException;

public class Main {
	static int N,M, minMemory;
	static int[] usingByteOfMemory, disabledByteOfMemory, dp;

	public static void main(String[] args) throws Exception {
		SetData();	
		minMemory = ReturnMinMemory();
		System.out.println(minMemory);
	}

	// 데이터
	private static void SetData() throws Exception  {
		InputReader in = new InputReader(System.in);
		
		N = in.readInt();
		M = in.readInt();
		
		usingByteOfMemory = new int[N];
		disabledByteOfMemory = new int[N];
		dp = new int[10001];
		Arrays.fill(dp, -1);
		minMemory = Integer.MAX_VALUE;
		
		for(int i = 0; i < N; i++)
			usingByteOfMemory[i] = in.readInt();
		
		for(int i = 0; i < N; i++)
			disabledByteOfMemory[i] = in.readInt();
	}
	
	private static int ReturnMinMemory() {		
		
		// dp[i]: i cost를 써서 확보할 수 있는 최대 메모리
		for(int i=0; i<N; i++){
			int cost = disabledByteOfMemory[i];
			// 뒤에서 부터 확인해야 겹치지 않고 값을 update 할 수 있다.
			for(int j=10000; j>=cost; j--){
				if(dp[j-cost] != -1){
					// 이전 j-cost 까지의 최대 값에 현재 memory를 더하는게 더 크다면 update
					if(dp[j-cost] + usingByteOfMemory[i] > dp[j])
						dp[j] = dp[j-cost] + usingByteOfMemory[i];
				}
			}
			// 메모리 업데이트가 안되어있는 경우 업데이트
			// 단 메모리가 더 큰 경우에만 업데이트 가능
			if(dp[cost] < usingByteOfMemory[i]) dp[cost] = usingByteOfMemory[i];
		}

		for(int i=0; i<10001; i++){
			// 최소 메모리 return
			if(dp[i] >= M){
				return i;
			}
		}
		return 0;
	}
    
	private static class InputReader {
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public int read() {
			if (numChars == -1) {
				throw new InputMismatchException();
			}
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0) {
					return -1;
				}
			}
			return buf[curChar++];
		}

		public int readInt() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9') {
					throw new InputMismatchException();
				}
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public boolean isSpaceChar(int c) {
			if (filter != null) {
				return filter.isSpaceChar(c);
			}
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}
	}
}

+ Recent posts