백준 windows [c++]

2044 windows 골드 3

문제 링크

문제

text-mode windows의 개발자인 동혁이는 “cascade mode (계단형 배치)” 부분을 코딩하다가 고심에 빠졌다. text-mode windows에서 하나의 window는 다음과 같이 ‘+’, ‘-’, ‘|’, ‘.’, 그리고 알파벳 소문자로 이루어져 있다.

+--|abcdef|---+
|.............|
|.............|
|.............|
|.............|
+-------------+

모든 window는 위와 같은 형태를 지키고 있으며, title을 기록할 수 있을 정도로 window는 넓다. (즉, title의 길이보다 모든 window는 적어도 6 이상은 가로로 길다. +-|, |-+가 들어가야 하므로) title은 가로로 정확히 가운데에 표시되어 있으며, 만일 위의 경우와 같이 window의 길이가 홀수인 경우 오른쪽이 왼쪽보다 하나 더 길다.

text-mode windows의 screen-shot이 주어졌다. 어떤 두 개의 window도 서로 겹치지 않게 배치되어 있다고 하자. 이때, 동혁이를 도와 다음과 같이 “cascade mode”로 window를 정리해 주는 프로그램을 작성하시오.

모든 window의 가로, 세로 크기는 변하지 않아야 한다. 모든 window들은 title의 알파벳 순서로 정렬한다. 모든 window들을 왼쪽 위 꼭짓점이 화면 전체의 왼쪽 위 꼭짓점이 되도록 옮긴다. 그리고 나서, 순서대로 한 칸씩 오른쪽 아래로 내려 배치한다.

입력

첫째 줄에 스크린의 세로 길이 M과 가로 길이 N이 주어진다. (10≤M, N≤100) 이어서 M개의 줄에는 각각 N개의 문자열이 주어지는데, 이는 screen-shot을 나타내 주는 정보이다. 배경 그림 같은 것은 없고 모두 ‘.’으로 표시되며, 모든 window의 title의 길이는 1 이상 10 이하이다. M과 N은 “cascade mode”로 window를 모두 정리할 수 있을 만큼 충분히 크다고 가정해도 좋다.

출력

M개의 줄에 걸쳐 “cascade mode”로 window를 모두 정리한 화면을 출력한다.

풀이

입력으로 들어오는 windows들에 대해 title, width, height 3가지 정보를 vector에 저장한뒤 title로 sorting한다.

이후 vector에 저장된 정보를 0,0에서부터 하나씩 출력하며 x,y를 1씩 늘려주면 된다.

0,0에서 출력하고 1,1에서 출력하면 먼저 출력한게 덮어쓰여 정답과 같이 출력된다.

신경 쓸 부분은 처음 입력에 대해 title, width, height를 저장하는 부분으로 구현만 잘하면 된다.

코드

#include <iostream>
#include <vector>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;

vector< pair<string, pair<int, int> > > v;
string windows[101];
bool visited[101][101];
int win[101][101];
int n, m;
int x = 0;
int y = 0;

void windowInfo(int i, int j){
    int width = 1;
    int height = 1;
    string word = "";
    while(windows[i][j + width] - '+' != 0){
        if(97 <= windows[i][j + width] && windows[i][j + width] <= 122) {
            word += windows[i][j + width];
        }
        width++;
    }
    width++;

    while(windows[i + height][j] - '+' != 0){
        height++;
    }
    height++;
    v.push_back(make_pair(word, make_pair(width, height)));
    visited[i][j] = true;
    visited[i+height-1][j] = true;
    visited[i][j+width-1] = true;
    visited[i+height-1][j+width-1] = true;
    
}

void printWindow() {
    // 
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            if(win[i][j] == 0){
                printf(".");
            } else if(win[i][j] == 1){
                printf("+");
            } else if(win[i][j] == 2){
                printf("-");
            } else if(win[i][j] == 3){
                printf("|");
            } else{
                printf("%c", win[i][j]);
            }
        }
        printf("\n");
    }
    return;
}

// width - string.len() - 4
void setWindow(vector< pair<string, pair<int, int> > > wnd, int idx){

    int width = wnd[idx].second.first;
    int height = wnd[idx].second.second;
    int minus = width - wnd[idx].first.size() - 4;
    int half = minus / 2;

    win[x][y] = 1;
    win[x][y + width - 1] = 1;
    for(int mi = 1; mi <= half; mi++)
    {
        win[x][y + mi] = 2;
    }
    win[x][y + half + 1] = 3;
    int startS = y + half + 2;
    for(int i = 0; i < static_cast<int>(wnd[idx].first.size()); i++)
    {
        win[x][startS + i] = wnd[idx].first[i];
    }
    startS += wnd[idx].first.size();
    win[x][startS] = 3;
    // startS++;
    if(minus % 2 == 0){
        for(int mi = 1; mi <= half; mi++)
        {
            win[x][startS + mi] = 2;
        }
    } else{
        for(int mi = 1; mi <= half + 1; mi++)
        {
            win[x][startS + mi] = 2;
        }
    }
    int innerH = height - 2;
    int innerW = width - 2;

    for(int h = 0; h < innerH; h++)
    {
        win[x + 1 + h][y] = 3;
        for(int w = 0; w < innerW; w++)
        {
            win[x + 1 + h][y + 1 + w] = 0;
        }
        win[x + 1 + h][y + 1 + innerW] = 3;
    }

    win[x + 1 + innerH][y] = 1;
    win[x + 1 + innerH][y + width - 1] = 1;

    for(int w = 0; w < innerW; w++)
    {
        win[x + 1 + innerH][y + 1 + w] = 2;
    }





    x++;
    y++;

}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    cin >> n >> m;

    for(int i = 0; i < n; i++)
    {
        cin >> windows[i];
        memset(visited[i], false, 101);
        memset(win[i], 0, 101);
    }

    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            if(windows[i][j] - '+' == 0 && visited[i][j] == false){
                windowInfo(i, j);
                // cout << i << " " << j << endl;
            }
        }
    }

    sort(v.begin(), v.end());

    for(size_t i = 0; i < v.size(); i++)
    {
        // cout << v[i].first << " " << endl;
        setWindow(v, static_cast<int>(i));
    }

    printWindow();


    return 0;
}