9019번: DSLR

네 개의 명령어 D, S, L, R 을 이용하는 간단한 계산기가 있다. 이 계산기에는 레지스터가 하나 있는데, 이 레지스터에는 0 이상 10,000 미만의 십진수를 저장할 수 있다. 각 명령어는 이 레지스터에

www.acmicpc.net

 

 

 

 


 

 

 

  • 풀이

 

DSLR 방식을 사용하여 최소의 방법으로 A에서 B의 값을 만들어내면 되는 문제입니다.

 

  • D: D 는 n을 두 배로 바꾼다. 결과 값이 9999 보다 큰 경우에는 10000 으로 나눈 나머지를 취한다. 그 결과 값(2n mod 10000)을 레지스터에 저장한다.
  • S: S 는 n에서 1 을 뺀 결과 n-1을 레지스터에 저장한다. n이 0 이라면 9999 가 대신 레지스터에 저장된다.
  • L: L 은 n의 각 자릿수를 왼편으로 회전시켜 그 결과를 레지스터에 저장한다. 이 연산이 끝나면 레지스터에 저장된 네 자릿수는 왼편부터 d2, d3, d4, d1이 된다.
  • R: R 은 n의 각 자릿수를 오른편으로 회전시켜 그 결과를 레지스터에 저장한다. 이 연산이 끝나면 레지스터에 저장된 네 자릿수는 왼편부터 d4, d1, d2, d3이 된다.

 

일단 위의 설명대로 하나씩 메소드를 만들어 값을 변경시킬 수 있도록 했습니다.

 

이제 정확하게 A에서 B로가는 최단명령어를 조사해야합니다. dfs를 사용할 경우 딥하게 들어가 stackoverflow가 발생할 수 있기때문에 bfs방식을 사용했습니다.

 

방식 ) class를 만들어 랜덤으로 DSLR을 하며 변경된 값과 command를 추가시켜주었습니다.

예외 ) check 배열을 만들어 같은 값이 또 나온 경우 같은 작업을 반복하지 않도록 해주었습니다.

 

문제에서 원하는 답은 같은 명령어의 길이이면 모두 정답이 되기 때문에 반복문을 통해 가장 먼저 B가 되는 값을 return 시켜주었습니다.

 

 

  • 코드

 

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

public class Main {
	static StringBuilder sb;
	static boolean[] check;
	
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		SetData();
		System.out.println(sb);
	}
	
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);
		
		int testcase = in.nextInt();
		sb = new StringBuilder();
		
		for(int i = 0; i < testcase; i++) {
			int a = in.nextInt();
			int b = in.nextInt();
			check = new boolean[10000];
			
			sb.append(bfs(a,b)).append("\n");
		}
	}
	
	private static String bfs(int a, int b) {
		Queue<Node> queue = new LinkedList<>();
		check[a] = true;
		queue.add(new Node(a, ""));
		
		while(!queue.isEmpty()) {
			Node node = queue.poll();
			
			if(node.value == b) {
				return node.command;
			}
			
			int valueAfterCommand = D(node.value);
			if(!check[valueAfterCommand]) {
				check[valueAfterCommand] = true;
				queue.add(new Node(valueAfterCommand, node.command+"D")) ;
			}
			
			valueAfterCommand = S(node.value);
			if(!check[valueAfterCommand]) {
				check[valueAfterCommand] = true;
				queue.add(new Node(valueAfterCommand, node.command+"S")) ;
			}
			
			valueAfterCommand = L(node.value);
			if(!check[valueAfterCommand]) {
				check[valueAfterCommand] = true;
				queue.add(new Node(valueAfterCommand, node.command+"L")) ;
			}
			
			valueAfterCommand = R(node.value);
			if(!check[valueAfterCommand]) {
				check[valueAfterCommand] = true;
				queue.add(new Node(valueAfterCommand, node.command+"R")) ;
			}
		}
		
		return "";
	}
	
	private static int D(int a) {
		return (a*2)%10000;
	}
	
	private static int S(int a) {
		a -=1;
		if(a==-1)
			return 9999;
		else
			return a;
	}
	
	private static int L(int a) {
		int temp = a%1000;
		int temp1 = a/1000;
		return temp*10+temp1;
	}
	
	private static int R(int a) {
		int temp = a % 10;
		int temp1 = a / 10;
		return temp*1000+temp1;
	}
}

class Node {
	int value;
	String command;
	
	public Node(int value, String command) {
		this.value = value;
		this.command = command;
	}
}

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 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;
	}
}

 

13023번: ABCDE

문제의 조건에 맞는 A, B, C, D, E가 존재하면 1을 없으면 0을 출력한다.

www.acmicpc.net

 

 

 

 


 

 

 

 

  • 풀이

 

처음에 문제를 읽고 이해가 되지않아서 해맸습니다.

 

정리하자면, 모든 노드 중 ABCDE의 예시처럼 5개의 노드가 예시의 입력이 주어지는 가를 맞추는 문제입니다.

즉, 모든 노드를 확인하며 ABCDE처럼 5개의 노드까지가면 1출력, 모든 노드가 ABCDE처럼 5개의 노드를 갈 수 없다면 0출력해주면 됩니다.

 

저는 ArrayList 배열을 통해 노드들을 연결했고, boolean 배열을 통해 방문을 체크해주었습니다.

돌리는 방식은 dfs방식으로 depth가 5이면 1을 출력하도록 했습니다.

 

 

  • 코드

 

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

public class Main {
	static ArrayList[] array;
	static boolean[] check;
	static int N, M, answer;
	
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		SetData();
		System.out.println(answer);
	}
	
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);
		
		N = in.nextInt();
		M = in.nextInt();
		answer = 0;
		array = new ArrayList[N];
		check = new boolean[N];
		for(int i = 0 ; i < N; i++)
			array[i] = new ArrayList<Integer>();
		
		
		for(int i = 0 ; i < M; i++) {
			int a = in.nextInt();
			int b = in.nextInt();
			
			array[a].add(b);
			array[b].add(a);
		}
		
		for(int i = 0 ; i < N; i++) {
			if(answer == 1) break;
			
			check[i] = true;
			dfs(i, 1);
			check[i] = false;
		}
	}
	
	private static void dfs(int index, int depth) {
		if(depth == 5) { 
			answer = 1;
			return;
		}
		
		for(int i = 0; i < array[index].size(); i++) {
			int temp = (int) array[index].get(i);
			if(check[temp]) continue;
			
			check[temp] = true;
			dfs(temp, depth+1);
			check[temp] = false;
		}
	}
}

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 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;
	}
}

 

1261번: 알고스팟

첫째 줄에 미로의 크기를 나타내는 가로 크기 M, 세로 크기 N (1 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 미로의 상태를 나타내는 숫자 0과 1이 주어진다. 0은 빈 방을 의미하고, 1은 벽을 의미

www.acmicpc.net

 

 

 

 

 

 


 

 

 

 

 

  • 풀이

 

일반적인 배열의 너비 우선 탐색에서 dist배열을 추가하여 더 적게 벽을 부순경우의 수만 queue에 추가하여 탐색해주었습니다.

 

Queue를 int[]인 배열로 만들어서 변수명[0]으로 꺼내오는 것 보단 Node라는 클래스를 만들어 좌표의 뜻을 품는 x, y의 좌표로 표현하였습니다. (변수의 의미 부여)

 

  • 코드

 

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

public class Main {
	static int N, M;
	static int[][] array;
	static int[][] dist;
	static int[] x = {0,0,-1,1};
	static int[] y = {-1,1,0,0};
	
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		SetData();
		System.out.println(dist[N-1][M-1]);
	}
	
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);
		
		M = in.nextInt();
		N = in.nextInt();
		array = new int[N][M];
		dist = new int[N][M];
		
		for(int i = 0; i < N; i++) {
			String s = in.nextLine();
			for(int j = 0; j < M; j++) {
				array[i][j] = s.charAt(j) - '0';
				dist[i][j] = 10000000;
			}
		}
		
		bfs();
	}
	
	private static void bfs() {
		Queue<Node> queue = new LinkedList<>();
		queue.add(new Node(0,0));
		dist[0][0] = 0;
		
		while(!queue.isEmpty()) {
			Node node = queue.poll();
			
			for(int i = 0; i < 4; i++) {
				int r = node.x + x[i];
				int c = node.y + y[i];
				
				if(r < 0 || c < 0 || r >= N || c >= M) continue;
				
				if (dist[r][c] > dist[node.x][node.y] + array[r][c]) {
					dist[r][c] = dist[node.x][node.y] + array[r][c];
					queue.add(new Node(r,c));
				}
			}
		}
	}
}

class Node {
	int x;
	int y;
	
	public Node(int x, int y) {
		this.x = x;
		this.y = y;
	}
}

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 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;
	}
}

 

2458번: 키 순서

1번부터 N번까지 번호가 붙여져 있는 학생들에 대하여 두 학생끼리 키를 비교한 결과의 일부가 주어져 있다. 단, N명의 학생들의 키는 모두 다르다고 가정한다. 예를 들어, 6명의 학생들에 대하여

www.acmicpc.net

 

 

 

 


 

 

 

  • 풀이

 

풀이 방식은 플로이드와샬을 사용했습니다.

 

자신보다 우선순위가 큰 값은 (i,j)를 1로 작은 값은 -1로 초기화 시켰습니다.

 

플로이드와샬 방식을 통해 배열을 돌며 자신의 큰 값보다 더 큰 값 또한 (i,j)를 1로 작은 값보다 더 작은 값은 -1로 초기화 시켜주었습니다.

 

 

  • 코드

 

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

public class Main {
	static int N, M;
	static int[][] array;
	static int answer;
	
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		SetData();
		System.out.println(answer);
	}
	
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);
		
		N = in.nextInt();
		M = in.nextInt();
		answer = 0;
		array = new int[N+1][N+1];
		
		for(int i = 0 ; i < M; i++) {
			int a = in.nextInt();
			int b = in.nextInt();
			array[a][b] = 1;
			array[b][a] = -1;
		}
		
		for(int k = 1; k <= N; k++) {
			for(int i = 1; i <= N; i++) {
				for(int j = 1; j <= N; j++) {
					if(array[i][k] + array[k][k] == 2)
						array[i][j] = 1;
					else if(array[i][k] + array[k][j] == -2)
						array[i][j] = -1;
				}
			}
		}
		
		
		for(int i = 1; i <= N; i++) {
			int count = 0;
			for(int j = 1; j <= N; j++) {
				if(array[i][j] != 0 || array[j][i] != 0)
					count++;
			}
			if(count == N-1) answer++;
		}
	}
}

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 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;
	}
}

 

11403번: 경로 찾기

가중치 없는 방향 그래프 G가 주어졌을 때, 모든 정점 (i, j)에 대해서, i에서 j로 가는 경로가 있는지 없는지 구하는 프로그램을 작성하시오.

www.acmicpc.net

 

 

 

 


 

 

 

 

  • 풀이

 

문제는 그래프 (i,j)에서 i에서 j로 가는 경로가 있는지 없는지 구해주는 문제입니다.

 

문제를 읽자마자 가장 먼저 생각난 알고리즘은 플로이드와샬이였습니다.

 

왜? 플로이드와샬이 바로 생각났는지에 대해 궁금해 하시는 분들이 있을 수 있을 것 같아 간단하게 설명을 드리자면 플로이드 와샬의 목적에 대해서 생각해볼 필요가 있습니다.

 

플로이드와샬의 목적은 모든 정점에서 모든 정점으로의 최단경로를 찾는 것 입니다. 플로이드의 기본 코드를 보면 k인덱스를 기준으로 i에서 j로 가는 가장 작은 가중치를 초기화 시켜줍니다. 

플로이드의 초기화 기본 코드는 array[i][j] = Math.min(array[i][j], array[i][k]+array[k][j])입니다. 현재 초기화된 값보다 i에서 k로 가는 경로와 k에서 j로 가는 경로의 값을 더한 값이 더 작다면 값을 초기화 시켜준다는 것 입니다.

 

이를 이어서 생각하면 array[i][k] + array[k][j]의 값이 2인 경우 i->k로 가는 경우도 있고 k->j로 가는 경우도 있다는 것을 의미합니다. 따라서 현재 array[i][j]값이 1이 아니여도 array[i][k]로 가는 경로가 있고 array[k][j]로 가는 경우가 있다면 array[i][j]를 갈 수 있다를 토대로 코드를 작성했습니다.

 

 

  • 코드

 

 

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

public class Main {
	static int N;
	static int[][] array;
	static StringBuilder sb;
	
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		SetData();
		System.out.println(sb);
	}
	
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);
		
		N = in.nextInt();
		sb = new StringBuilder();
		array = new int[N][N];
		
		for(int i = 0; i < N; i++) {
			for(int j = 0; j < N; j++) {
				array[i][j] = in.nextInt();
			}
		}
		
		for(int k = 0; k < N; k++) {
			for(int i = 0; i < N; i++) {
				for(int j = 0; j < N; j++) {
					// j까지 도달한다면
					if(array[i][k] + array[k][j] == 2) {
						array[i][j] = 1;
					}
				}
			}
		}
		
		for(int i = 0; i < N; i++) {
			for(int j = 0; j < N; j++) {
				sb.append(array[i][j] + " ");
			}
			sb.append("\n");
		}
	}
}

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 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;
	}
}

 

1707번: 이분 그래프

입력은 여러 개의 테스트 케이스로 구성되어 있는데, 첫째 줄에 테스트 케이스의 개수 K가 주어진다. 각 테스트 케이스의 첫째 줄에는 그래프의 정점의 개수 V와 간선의 개수 E가 빈 칸을 사이에

www.acmicpc.net

 

 

 


 

 

 

  • 풀이

 

 

문제 설명을 보고 이해가 가지않아서 다른 분이 정리해놓은 해설을 듣고 이해했습니다.

 

이분 그래프란 인접한 그래프끼리의 색은 같지 않아야하는 그래프입니다. 색은 두개면 표현할 수 있기 때문에 boolean을 통해 현재 그래프가 true라면 인접한 그래프는 false로 체크해주며 bfs시켰습니다.

 

모든 그래프를 체크했다면 실제로 인접한 그래프끼리의 색이 다른지 확인해주면 됩니다.

 

*참고*

이분 그래프를 bfs를 돈 결과 (true - 파란색, false 그린)

 

 

이분 그래프가 아닌 그래프를 위의 식대로 bfs를 돈 결과 (true - 파란색, false 그린)

 

 

  • 코드

 

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

public class Main {
	static StringBuilder sb;
	static ArrayList[] array;
	static boolean[] check, color;
	
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		SetData();
		System.out.println(sb);
	}
	
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);
		
		int testcase = in.nextInt();
		sb = new StringBuilder();
		
		for(int i = 0 ; i < testcase; i++) {
			int V = in.nextInt();
			int E = in.nextInt();
			array = new ArrayList[V + 1];
			check = new boolean[V+1];
			color = new boolean[V+1];

			for (int j = 1; j <= V; j++) { 
				array[j] = new ArrayList<Integer>();
			}
			
			for(int j = 0 ; j < E; j++) {
				int u = in.nextInt();
				int v = in.nextInt();
				
				array[u].add(v);
				array[v].add(u);
			}
			
			for (int j = 1; j <= V; j++) {
				if (check[j]) continue;
				
				bfs(j, false);
			}
			
			boolean isBipartite = false;
			for (int j = 1; j <= V; j++) {
				for(int a = 0 ; a < array[j].size(); a++) {
					if (color[j] == color[(int) array[j].get(a)]) {
						isBipartite = true;
						break;
					}
				}
			}
			
			if (!isBipartite) {
				sb.append("YES").append("\n");
			} else {
				sb.append("NO").append("\n");
			}
		}
	}
	
	private static void bfs(int index, boolean nowColor) {
		check[index] = true;
		color[index] = nowColor;
		
		for(int i = 0 ; i < array[index].size(); i++) {
			int value = (int) array[index].get(i);
			
			if(check[value]) continue;
			bfs(value, !nowColor);
		}
	}
}

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 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;
	}
}
 

코딩테스트 연습 - 10주차

[[2, -1, 4], [-2, -1, 4], [0, -1, 1], [5, -8, -12], [5, 8, 12]] ["....*....", ".........", ".........", "*.......*", ".........", ".........", ".........", ".........", "*.......*"] [[0, 1, -1], [1, 0, -1], [1, 0, 1]] ["*.*"] [[1, -1, 0], [2, -1, 0], [4, -

programmers.co.kr

 

 

 


 

 

  • 풀이

 

 

친절하게 위와같은 설명이 있다. 위의 방식을 참고하여 구현했습니다.

 

반복문은 모든 선분끼리 교점이 있는지 없는지 반복작업 해주었습니다.

 

반복문을 돌면서 교점이 있는 경우 교점은 Set을 통해 저장해주었습니다.

(Set을 사용한 이유는 중복값을 체크해주지 않아도되고, 꺼내서 사용할 용도가 아닌 포함 여부만 판단할 것이기때문에 순서가 상관없어서 다른 Collection보다 빠르다.)

 

set에 저장하며 가장 왼쪽, 가장 오른쪽, 가장 위, 가장아래 index를 업데이트 시킵니다.

 

위의 반복문이 끝난 뒤, 가장 위 index부터 가장왼쪽index~가장오른쪽index의 반복을 가장 아래 index까지 반복하며 set에 있는 교점은 *를 추가, 교점이 없는 경우 .를 추가했습니다.

 

 

 

 

  • 코드

 

import java.util.*;

class Solution {
    public String[] solution(int[][] line) {
        int minC = Integer.MAX_VALUE;
        int minR = Integer.MAX_VALUE;
        int maxC = Integer.MIN_VALUE;
        int maxR = Integer.MIN_VALUE;
        // 위치 저장해줄 set함수
        Set<String> set = new HashSet<>();
        for(int i=0; i<line.length-1; i++) {
            for(int j=i+1; j<line.length; j++) {
                int temp = line[i][0]*line[j][1] - line[i][1]*line[j][0];
                int temp1 = line[i][1]*line[j][2] - line[i][2]*line[j][1];
                int temp2 = line[i][2]*line[j][0] - line[i][0]*line[j][2];
                if(temp == 0 || temp1%temp != 0 || temp2%temp != 0) 
                    continue;
                
                int x = temp1/temp;
                int y = temp2/temp;
                
                set.add(x+","+y);
                minR = Math.min(minR, x);
                minC = Math.min(minC, y);
                maxR = Math.max(maxR, x);
                maxC = Math.max(maxC, y);
            }
        }
        // 교점이 없는 경우
        if(minR == Integer.MAX_VALUE) {
            String[] answer = new String[1];
            answer[0] = "*";
            return answer;
        }
        
        // 위 맨 왼쪽 ~ 아래 맨 오른쪽까지
        String[] answer = new String[maxC-minC+1];
        int index = 0;
        for(int i = maxC; i >= minC; i--){
            StringBuilder sb = new StringBuilder();
            for(int j = minR; j <= maxR; j++){
                if(set.contains(j+","+i)){
                    sb.append("*");
                }
                else
                    sb.append(".");
            }
            answer[index++] = sb.toString(); 
        }
        return answer;
    }
}
 

코딩테스트 연습 - 가장 먼 노드

6 [[3, 6], [4, 3], [3, 2], [1, 3], [1, 2], [2, 4], [5, 2]] 3

programmers.co.kr

 

 

 


 

 

 

 

  • 풀이

 

노드1이랑 연결되어있는 노드들은 첫번째로 먼 노드들입니다.

첫번째 노드랑 연결되어 있는 (지나쳐오지 않은)노드들은 노드1이랑 두번째로 멀리 연결되어 있는 노드들입니다.

......쭉 마지막으로 연결되어 있는 노드까지 가서 개수를 구해주었습니다.

 

 

  • 코드

 

import java.util.*;

class Solution {
    public int solution(int n, int[][] edge) {
        boolean[][] node = new boolean[n+1][n+1];
        boolean[] check = new boolean[n+1];
        for(int i = 0 ; i < edge.length; i++){
            node[edge[i][0]][edge[i][1]] = true;
            node[edge[i][1]][edge[i][0]] = true;
        }
        
        Queue<Integer> queue = new LinkedList<>();
        int answer = 0;
        queue.add(1);
        
        while(!queue.isEmpty()) {
            answer = queue.size();
            
            for(int i = 0; i < answer; i++) {
                int pre = queue.poll();
                
                for(int next = 2; next <= n; next++){
                    if(check[next] || !node[pre][next]) continue;
                    check[next] = true;
                    queue.add(next);
                }
            }
        }
        
        return answer;
    }
}

+ Recent posts