삼항 연산자에 대해 알아보자.

 

조건식? 식1 : 식2

 

위와 같이 사용되는데, 조건식이 참이라면 식1이 실행되고, 거짓이라면 식2가 실행된다는 의미이다.

 

package pjtTest;

public class MainClass {
	public static void main(String[] args) {
		int Big = 10, Small = 5;
		boolean result;
		result = (Big > Small) ? true : false;
		System.out.printf("result = %b", result);
	}
}

 

 

'Programming Language > Java' 카테고리의 다른 글

비트 연산자  (0) 2019.07.27
서식 문자의 사용  (0) 2019.07.27

자바에서는 System.out..println("");으로 출력을 하곤 한다.

 

하지만 C++에서 익숙하게 사용해오던 %d, %c 등의 서식 문자를 사용하기 위해서는  println을 printf로 바꿔서 사용해줘야 한다.

 

f가 format의 약자라서 그렇다고 한다. 또한 println은 개행(줄 바꿈)을 포함하고 있다. 하지만 printf는 개행이 포함되지 않기 때문에 줄 바꿈을 직접 해줘야 한다.

 

10진수로 %d를 사용했다면, 8진수는 %o 16진수는 %x를 사용한다.

 

또한 정수와 실수의 자릿수를 제한할 때도 서식 문자를 사용할 수 있다.

 

정수의 경우, 오른쪽 정렬을 할 때에 서식문자를 활용하여 아래와 같이 할 수 있고,

 

실수의 경우에는, %.숫자f를 활용하여 소수점 자릿수를 제한할 수 있다.

package pjtTest;

public class MainClass {
	public static void main(String[] args) {
		//여러개의 클레스를 만들어 놓거나 하면, 컴퓨터는 뭘 실행해야 할지 모른다.
		//main 메소드부터 실행한다.
		
		//10의 10, 8, 16진수 출력
		int num = 10;
		System.out.printf("10진수 %d\n",num);
		System.out.printf("8진수 %o\n", num);
		System.out.printf("16진수 %x\n", num);
		System.out.println("\n");
		
		//숫자들을 오른쪽 정렬해서 출력하고 싶을 때
		System.out.printf("%5d\n",123);
		System.out.printf("%5d\n",1234);
		System.out.printf("%5d\n",12345);
		
		//소수점 자리수를 제한하고 싶을 때
		double num2 = 3.141592;
		System.out.printf("%.1f\n",num2);
		System.out.printf("%.3f\n",num2);
		System.out.printf("%.5f\n",num2);
	}
}

 

'Programming Language > Java' 카테고리의 다른 글

비트 연산자  (0) 2019.07.27
조건(삼항) 연산자  (0) 2019.07.27

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

 

16234번: 인구 이동

N×N크기의 땅이 있고, 땅은 1×1개의 칸으로 나누어져 있다. 각각의 땅에는 나라가 하나씩 존재하며, r행 c열에 있는 나라에는 A[r][c]명이 살고 있다. 인접한 나라 사이에는 국경선이 존재한다. 모든 나라는 1×1 크기이기 때문에, 모든 국경선은 정사각형 형태이다. 오늘부터 인구 이동이 시작되는 날이다. 인구 이동은 다음과 같이 진행되고, 더 이상 아래 방법에 의해 인구 이동이 없을 때까지 지속된다. 국경선을 공유하는 두 나라의 인구 차이가 L명

www.acmicpc.net

bfs 혹은 dfs를 활용하여 해결할 수 있다.

 

인구이동 조건과, 방문 여부가 탐색 진행의 기준이 된다.

 

for(for(bfs)) 구조로 해결할 수 있다.

 

for(for 을 완전히 탈출할 때 까지가 한 번의 인구이동 날이라고 할 수 있다.

 

따라서 이를 무한루프로 감싸서, 인구의 이동이 없는 경우 무한루프를 탈출하는 구조로 해결하면 된다.

 

 

그런데, 인구 이동 조건을 만족하더라도, 그 자리에서 인구수를 바로 갱신할 수가 없다.

 

일단 국경을 개방할 수 있는 지점을 모두 찾아내야 하기 때문에, 일단 한 번의 bfs가 다 종료되어야 인구수를 갱신할 수 있다. 방문처리된 지점들(큐에 삽입된 적이 있는 지점들)이 갱신의 대상이기 때문에, 이 좌표들을 차례로 백터에 저장해준다.

 

이후에 벡터의 크기가 연합국의 숫자이고, 인구수의 합은 큐에 삽입하면서 기억해 둘 것이다.

 

한번의 인구 이동이 모두 끝났는데, 변화가 없다면 무한 루프를 종료하고, 그렇지 않다면 방문처리 배열을 초기화해준 이후에 인구이동을 다시 시작해주면 된다.

 

#include<iostream>
#include<queue>
#include<math.h>
#include<vector>
using namespace std;
int N, L, R, m[51][51];
bool bor[51][51]; //방문 처리 배열
int dr[4] = { 0, 0, 1, -1 };
int dc[4] = { 1, -1, 0, 0 };

queue<pair<int, int> > q;
bool updated = false;
int idxSum = 0;
vector<pair<int, int> > v;
void bfs(pair<int, int> start) {
	q.push(start);
	bor[start.first][start.second] = true;

	while (!q.empty()) {
		pair<int, int> cur = q.front();
		q.pop();
		
		for (int i = 0; i < 4; i++) {
			int nr = cur.first + dr[i];
			int nc = cur.second + dc[i];
			if (nr < 0 || nc < 0 || nr >= N || nc >= N || bor[nr][nc])
				continue;
			if (abs(m[nr][nc] - m[cur.first][cur.second]) >= L &&
				abs(m[nr][nc] - m[cur.first][cur.second]) <= R) {
				q.push({ nr, nc });
				bor[nr][nc] = true; 
				
				v.push_back({ nr, nc });
				idxSum += m[nr][nc];
			}
		}
	}
}
void init() {
	for (int i = 0; i < N; i++) 
		for (int j = 0; j < N; j++) 
			bor[i][j] = 0;
}
int main(void) {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> L >> R;
	for (int i = 0; i < N; i++)
		for (int j = 0; j < N; j++)
			cin >> m[i][j];

	int res = 0;
	while (1) {
		updated = false;
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (!bor[i][j]) {
					v.clear();
					v.push_back({ i,j }); 
					idxSum = m[i][j];
					bfs({ i, j });
				}
				//열린 국경이 있으면
				if (v.size() >= 2) { //한 연합 내의 국가 개수
					updated = true;
					int val = idxSum / v.size();
					for (int i = 0; i < v.size(); i++) {
						m[v[i].first][v[i].second] = val;
					}
				}
			}
		}
		if (updated) res++;
		else break;
		init();
	}
	cout << res << '\n';
	return 0;
}

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

 

17281번: ⚾

⚾는 9명으로 이루어진 두 팀이 공격과 수비를 번갈아 하는 게임이다. 하나의 이닝은 공격과 수비로 이루어져 있고, 총 N이닝동안 게임을 진행해야 한다. 한 이닝에 3아웃이 발생하면 이닝이 종료되고, 두 팀이 공격과 수비를 서로 바꾼다. 두 팀은 경기가 시작하기 전까지 타순(타자가 타석에 서는 순서)을 정해야 하고, 경기 중에는 타순을 변경할 수 없다. 9번 타자까지 공을 쳤는데 3아웃이 발생하지 않은 상태면 이닝은 끝나지 않고, 1번 타자가 다시 타석에

www.acmicpc.net

선수 9명의 순서를 결정해야 한다. 4번 타자는 1번 선수로 고정되어 있기 때문에 이를 반영해준다.

 

이닝별로 선수들의 결과를 입력으로 받는다.

 

따라서 모든 순열을 구해서 선수들의 순서를 만들어낸 이후에, 야구의 조건을 구현해주면 된다.

 

 

1루, 2루 등에 진출해 있는 선수들에 대한 관리는, 선수 번호를 그대로 인덱스로 해서 배열을 두었다.

 

1이면 1루에 있다는 뜻이고, 2면 2루 3이면 3루에, 

4 이상이 되면 홈으로 들어왔다는 의미이다.

 

각 이닝별로 선수들의 수행을 그대로 따라가면서 시뮬레이션을 진행해주면 된다.

 

res[][] 배열은 이닝별 선수의 득점이다.

 

num은 1~9까지 선수들 중에 9명을 뽑는 경우의 수로 사용한다.

 

ord는 뽑아서 결정된 선수들의 순서이다. ord[i]는 i번 타자를 의미한다.

 

#include<iostream> //2백만
#include<vector>
using namespace std;
int n, res[52][10], num[10], ord[10], pos[10], Max = -1;
bool isused[10];
void play() {
	int hitter = 1, score = 0;
	for (int i = 1; i <= n; i++) { //i이닝에
		int outCnt = 0;

		while (1) {
			if (res[i][ord[hitter]] == 0) { //아웃인 경우
				hitter++;
				if (hitter >= 10) hitter = 1;
				outCnt++;
				if (outCnt == 3) {
					//이닝 교체
					for (int j = 1; j <= 9; j++) pos[j] = 0;
					break;
				}
			}
			else {
				//득점타
				for (int j = 1; j <= 9; j++) {
					if (pos[j] > 0 || j == ord[hitter]) { //타석에 나가 있는 선수라면
						pos[j] += res[i][ord[hitter]];
						if (pos[j] >= 4) {
							//홈에 들어오면
							pos[j] = 0;
							score++;
						}
					}
				}
				hitter++;
				if (hitter >= 10) hitter = 1;
			}
		}
	}
	if (Max < score) Max = score;
}
void func(int k) {
	if (k > 9) { //base condition
		play();
		return;
	}
	for (int i = 2; i <= 9; i++) {
		if (!isused[i]) {
			ord[k] = i;
			isused[i] = true;
			if (k == 3) func(k + 2); //3번엔 다음 4번이 아니라 5번을 정함
			else func(k + 1);
			isused[i] = false;
		}
	}
}
int main(void) {
	for (int i = 1; i <= 9; i++)
		num[i] = i;
	isused[1] = true; //1은 항상 사용중
	ord[4] = 1; // 4번 선수는 항상 1
	cin >> n;
	
	for (int i = 1; i <= n; i++) 
		for (int j = 1; j <= 9; j++) 
			cin >> res[i][j];
	
	func(1);
	cout << Max << '\n';
	return 0;
}

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

 

17144번: 미세먼지 안녕!

미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기의 칸으로 나눴다. 구사과는 뛰어난 코딩 실력을 이용해 각 칸 (r, c)에 있는 미세먼지의 양을 실시간으로 모니터링하는 시스템을 개발했다. (r, c)는 r행 c열을 의미한다. 공기청정기는 항상 왼쪽 열에 설치되어 있고, 크기는 두 행을 차지한다. 공기청정기가 설치되어 있지 않은 칸에는 미세먼

www.acmicpc.net

 

약간의 bfs와 시뮬레이션이 혼합된 문제이다.

 

입력을 받은 이후에, 먼지가 있는 곳을 미리 큐에 넣어준다. 동시에 확산되어야 한다는 조건이 있기 때문이다.

 

미리 큐에 넣어주고, 한 번 탐색을 했을 때 큐의 크기만큼만 확산을 진행하면 단위 시간이 흘렀다고 볼 수 있다.

 

그리고, 이전에 발생했던 먼지의 확산이, 앞으로 발생하게 될 먼지의 확산에 영향을 끼치지 않게 하기 위해서

 

변화량을 따로 저장한 이후에, 확산을 마치고 변화량을 모두 구한 이후에 한꺼번에 반영해줘야 한다.

 

그렇지 않으면 동시에 확산했다는 조건을 만족시킬 수 없기 때문이다.

 

 

다음으로 환기에 대한 조건을 구현할 때는, 조건에 맞게 인덱스를 가지고 놀아주면 된다.

 

한 가지 주의할 사항은, 환기의 순서를 신경 써야 한다는 것이다.

 

먼저 빨려들어가서 없어지는 먼지의 값을 덮어 씌워주는 방향으로 순서를 정해야, 중간에 다른 구석 지점에서 먼지의 값이 누락되는 것을 방지할 수 있다.

 

따라서 먼저 빨려들어가는 쪽에 대한 처리를 먼저 해주는 방식으로 구현한다.

 

#include<iostream>
#include<queue>
using namespace std;
int m[52][52], T, R, C, dif[52][52];
bool vis[52][52];
pair<int, int> Up;
pair<int, int> Dn;
queue<pair<int, int> > q;
int dr[4] = { 0,0,1,-1 };
int dc[4] = { 1,-1,0,0 };
void clean() {
	//상부
	for (int i = 1; i <= Up.first - 1; i++)  //하향
		m[Up.first - i][0] = m[Up.first - 1 - i][0];
	for (int i = 0; i <= C - 2; i++) //좌향
		m[0][i] = m[0][i + 1];
	for (int i = 0; i <= Up.first - 1; i++) //상향
		m[i][C - 1] = m[i + 1][C - 1];
	for (int i = C - 1; i >= 1; i--) //우향
		m[Up.first][i] = m[Up.first][i - 1];


	//하부
	for (int i = Dn.first + 1; i <= R - 2; i++) //상향
		m[i][0] = m[i + 1][0];
	for (int i = 1; i <= C - 1; i++) //좌향
		m[R - 1][i - 1] = m[R - 1][i];
	for (int i = R - 1; i >= Dn.first + 1; i--)//하향
		m[i][C - 1] = m[i - 1][C - 1];

	for (int i = C - 1; i >= 1; i--) //우향
		m[Dn.first][i] = m[Dn.first][i - 1];
}

void bfs() {
	int cnt = q.size();
	while (cnt--) {
		pair<int, int> cur = q.front();
		q.pop();
		for (int i = 0; i < 4; i++) {
			int nr = cur.first + dr[i];
			int nc = cur.second + dc[i];
			if (nr < 0 || nc < 0 || nr >= R || nc >= C ) continue;
			if (nr == Up.first && nc == Up.second) continue;
			if (nr == Dn.first && nc == Dn.second) continue;
			
			dif[cur.first][cur.second] -= m[cur.first][cur.second] / 5;
			dif[nr][nc] += m[cur.first][cur.second] / 5;
		}
	}
	//update
	for (int i = 0; i < R; i++) {
		for (int j = 0; j < C; j++) {
			m[i][j] += dif[i][j];
		}
	}
	//Print();
	clean();
}
void init() {
	for (int i = 0; i < R; i++) {
		for (int j = 0; j < C; j++) {
			vis[i][j] = false;
			dif[i][j] = 0;
		}
	}
}
int main(void) {
	cin >> R >> C >> T;
	bool fst = true;
	for (int i = 0; i < R; i++) {
		for (int j = 0; j < C; j++) {
			cin >> m[i][j];
			if (m[i][j] == -1) {
				m[i][j] = 0;
				if (fst) {
					Up.first = i;
					Up.second = j;
					fst = false;
				}
				else {
					Dn.first = i;
					Dn.second = j;
				}
			}
		}
	}
	
	//1초 루틴
	while (T--) {
		for (int i = 0; i < R; i++) {
			for (int j = 0; j < C; j++) {
				if (m[i][j] != 0 && !vis[i][j]) { //방문 조건도 사실 필요없음
					q.push({ i, j });
					vis[i][j] = true;
				}
			}
		}
		bfs();
		init();
	}
	int Sum = 0;
	for (int i = 0; i < R; i++)
		for (int j = 0; j < C; j++)
			Sum += m[i][j];
	cout << Sum << '\n';
	return 0;
}

+ Recent posts