BOJ 2044

windows

문제출처

문제 해석

  • 주어진 조건을 따라서 구현하는 문제입니다.
  • 알파벳 소문자와, ‘+’,’-‘,’.’ 로 구성되어있습니다.
  • windows는 적어도 title길이보다 6 이상 가로로 길어야 합니다.
  • windows의 길이가 홀수인 경우 오른쪽을 왼쪽보다 하나 더 길게 합니다.
  • 각 window에 대해 다음 명령을 수행합니다.
    1. 모든 window의 가로,세로 길이는 변하지 않습니다.
    2. title의 사전순으로 window를 정렬합니다.
    3. 가장 위쪽 모서리부터 채우고, window가 하나 늘어날때마다 오른쪽 아래 한칸 부터 시작합니다.

설계(20)

  • 2차원 배열을 모두 탐색하면서 문자가 나오는 지점을 기준으로 height,width를 계산합니다.
  • title 사전순 정렬을 위해 {title, height, width} 정보가 들어있는 구조체를 사용하였습니다.
  • 사전순 정렬 후, (height,width)범위를 초기화(‘.’)한 다음 문자를 넣습니다.

구현(25)

코드
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
#define MAXN 100

char map[MAXN][MAXN];
char ans[MAXN][MAXN];
int N, M;
struct node {
	string s;
	int height;
	int width;
	bool operator < (const node& a) {
		return s < a.s;
	}
};
vector<node> v;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> M;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> map[i][j];
			ans[i][j] = '.';
		}
	}
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			
			if (map[i][j] >= 'a' && map[i][j] <= 'z') {
				int idx = j;
				int height = 1;
				int width = 1;
				string tmp_s = "";
				while (idx > 0 && map[i][idx--] != '+') width++;
				idx = j;
				while (map[i][idx] != '+') {
					if (map[i][idx] >= 'a' && map[i][idx] <= 'z') tmp_s += map[i][idx];
					width++;
					idx++;
				}
				
				int tmp_j = j;
				j = idx;
				idx = i;
				while (map[idx++][tmp_j] != '-') height++;
				v.push_back({ tmp_s,height,width });
			}
		}
	}
	sort(v.begin(), v.end());
	int sx = 0;
	int sy = 0;
	for (int i = 0; i < v.size(); i++) {
		int height = v[i].height;
		int width = v[i].width;
		string tmp_s = v[i].s;
		for (int x = sx; x < sx + height; x++) {
			for (int y = sy; y < sy + width; y++) {
				ans[x][y] = '.';
			}
		}
		int start_title = sy+(width - tmp_s.length()) / 2;
		for (int y = sy; y < start_title; y++) {
			if (y == sy) ans[sx][y] = '+';
			else if (y == start_title - 1) ans[sx][y] = '|';
			else ans[sx][y] = '-';
		}
		for (int y = 0; y < tmp_s.length(); y++) {
			ans[sx][y + start_title] = tmp_s[y];
		}
		for (int y = start_title + tmp_s.length(); y < sy + width; y++) {
			if (y == start_title + tmp_s.length()) ans[sx][y] = '|';
			else if (y == sy + width - 1) ans[sx][y] = '+';
			else ans[sx][y] = '-';
		}
		for (int x = sx + 1; x < sx + height; x++) {
			if (x >= sx + 1 && x < sx + height - 1) {
				ans[x][sy] = '|';
				ans[x][sy + width - 1] = '|';
			}
			else {
				for (int y = sy; y < sy + width; y++) {
					if (y == sy || y == sy + width - 1) ans[x][y] = '+';
					else ans[x][y] = '-';
				}
			}
		}
		sx++;
		sy++;
	}
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++){
			cout << ans[i][j];
		}
		cout << "\n";
	}
	return 0;
}
디버깅
  • while문 사용시, 인덱스 처리가 미흡하여 디버깅을 통해 수정하였습니다.
제출결과
  • 0ms

마무리

  • 구현 + 정렬 문제입니다. 위에서 설명한 그대로 따라하기만 하면 되는 문제이지만 구현능력을 키우기 위해 풀어봤습니다.