본문 바로가기

백준/애드혹,구성적

백준 13269 - 쌓기나무

728x90
728x90

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

힌트

더보기

만드는 게 우선이다. 일단 주어진 조건에서 가장 적절한 배치를 만들어라.

해설

더보기

위에서 본 view(이하 top_view), 앞으로 본 view(이하 front_view)와 옆에서 본 view(이하 side_view)가 주어질 때 가능한 상태인지 확인하고 실례를 출력하는 문제이다.

 

일단 top_view를 입력 받는다. 다음으로 front_view와 side_view를 받으면서 top_view[i][j]의 상태와 front_view[j], side_view[i]의 상태가 모순인지 확인한다. side_view는 왼쪽에서 본 순서로 주어진다는 것을 유의한다.

 

예를 들어서 설명하면 top_view[i][j]가 0인데 front_view[j]가 1이상 값을 가질 수 없다. 반대도 마찬가지. 이런 경우를 먼저 걸러주도록 한다.

 

side_view의 최댓값과 front_view의 최댓값이 일치한지 확인한다. 어디서 보든 가장 높은 높이는 유일해야 한다. 그런데 최댓값이 일치하지 않으면 모순이므로 -1을 출력한다.

 

그러고 나서 일단 나무를 쌓아보자. ans[i][j] = min(side_view[i], front_view[j])로 나무를 쌓는다. 이 식의 의미는 ans[i][j]를 어떻게 보든 min(side_view[i], front_view[j])보다 클 수는 없다는 뜻이다.

 

설명이 이해되지 않는다면 Pizza Boxes를 풀고 올 것을 권고한다.

 

나무를 쌓으면서 우리가 만든 배치의 view를 기록한다. 그리고 다 쌓았을 때 입력으로 주어진 view와 우리가 만든 view를 대조해서 일치하면 배치를 출력하고 그렇지 않으면 어딘가 모순이 발생했다는 뜻이므로 -1을 출력하면 된다.

 

전체 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,avx,avx2,fma")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
 
#include "bits/stdc++.h"
#include "ext/rope"
 
using namespace std;
using namespace __gnu_cxx;
 
using pii = pair<intint>;
using ll = long long;
 
int n, m;
int top_view[501][501];
int front_view[501];
int side_view[501];
bool row_see[501];
bool col_see[501];
int ans[500][500];
int front_const[501];
int side_const[501];
int mx, mx2;
 
void solve()
{
  cin >> n >> m;
 
  for (int i = 0; i < n; i++)
  {
    for (int j = 0; j < m; j++)
    {
      cin >> top_view[i][j];
      
      if (top_view[i][j])
      {
        row_see[i] = col_see[j] = true;
      }
    }
  }
 
  for (int i = 0; i < m; i++)
  {
    cin >> front_view[i];
    mx = max(mx, front_view[i]);
 
    int x = front_view[i] != 0;
 
    if (x ^ col_see[i])
    {
      cout << -1;
      return;
    }
  }
 
  for (int i = n - 1; i >= 0; i--)
  {
    cin >> side_view[i];
    mx2 = max(mx2, side_view[i]);
 
    int x = side_view[i] != 0;
 
    if (x ^ row_see[i])
    {
      cout << -1;
      return;
    }
  }
 
  if (mx != mx2)
  {
    cout << -1;
    return;
  }
 
  for (int i = 0; i < n; i++)
  {
    int lim = side_view[i];
    for (int j = 0; j < m; j++)
    {
      if (top_view[i][j])
      {
        ans[i][j] = min(lim, front_view[j]);
      }
 
      side_const[i] = max(side_const[i], ans[i][j]);
      front_const[j] = max(front_const[j], ans[i][j]);
    }
  }
 
  for (int i = 0; i < n; i++)
  {
    if (side_const[i] != side_view[i])
    {
      cout << -1;
      return;
    }
  }
 
  for (int i = 0; i < m; i++)
  {
    if (front_view[i] != front_const[i])
    {
      cout << -1;
      return;
    }
  }
 
  for (int i = 0; i < n; i++)
  {
    for (int j = 0; j < m; j++)
    {
      cout << ans[i][j] << ' ';
    }
    cout << '\n';
  }
}
 
int main()
{
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
 
  solve();
}
cs

제출 기록

728x90
728x90

'백준 > 애드혹,구성적' 카테고리의 다른 글

[ICPC] 백준 14961 - Untangling Chain  (0) 2022.08.02
백준 12095 - 가장 오래 걸리는 스도쿠  (0) 2022.06.06
백준 13019 - A를 B로  (0) 2022.04.17
백준 2873 - 롤러코스터  (0) 2022.04.07