문제 링크: https://www.acmicpc.net/problem/1089

 

고장났을수도 있는 엘리베이터 숫자를 보고 가능한 후보 숫자들의 평균을 구하는 문제입니다.

각 자리수마다 숫자를 판별하는건 귀찮지만 어렵지는 않습니다. 0~9까지 모양을 배열로 만들어서 하나씩 체크하면 됩니다.

고장난 부분도 고려를 해서 가능한 숫자 후보를 뽑아야 합니다. 원래 숫자에서는 불이 꺼져있는데 엘리베이터에서는 불이 켜져있는 부분이 있다면 그 숫자는 불가능합니다. 불이 고장나면 꺼지기만 하기 때문입니다.

 

그 외 고려해야 하는 사항이 몇 가지 있습니다.

 

...
.#.
...
.#.
...

1. 숫자로 만들 수 없는 경우

고장난 불이 있을 수도 있는데 고장난 불은 꺼지기만 하고 켜지지 않는게 켜지는 사항은 없습니다. 그래서 위 모양처럼 가능한 숫자가 없는 경우 -1을 출력합니다

 

9
..#...#...#...#...#...#...#...#...#
...................................
..#...#...#...#...#...#...#...#...#
...................................
..#...#...#...#...#...#...#...#...#

2. 시간초과

위 케이스의 경우 출력은 499999999.5 입니다.

각 자리수마다 0~9가 들어올 수 있고, 최대 9자리가 되니까 브루트포스로 가능한 수를 전부 만들면 시간초과가 나옵니다.

그러니 자리수마다 평균을 구하고, 그 값들을 더해 전체 수의 평균을 구해야 합니다.

예를 들어 n=2, 십의 자리수 후보가 (6, 8, 9), 일의 자리수 후보가 (0, 3, 8, 9)라고 하면 avg(6,8,9)*10 + avg(0,3,8,9) 이 값이 전체 평균이 됩니다.

 

#pragma GCC optimize ("Ofast")

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;


int n;
bool on[5][35];
constexpr bool NUMBERS_SHAPE[10][5][3] = {
	{ // 0
		{1,1,1},
		{1,0,1},
		{1,0,1},
		{1,0,1},
		{1,1,1},
	},
	{ // 1
		{0,0,1},
		{0,0,1},
		{0,0,1},
		{0,0,1},
		{0,0,1},
	},
	{ // 2
		{1,1,1},
		{0,0,1},
		{1,1,1},
		{1,0,0},
		{1,1,1},
	},
	{ // 3
		{1,1,1},
		{0,0,1},
		{1,1,1},
		{0,0,1},
		{1,1,1},
	},
	{ // 4
		{1,0,1},
		{1,0,1},
		{1,1,1},
		{0,0,1},
		{0,0,1},
	},
	{ // 5
		{1,1,1},
		{1,0,0},
		{1,1,1},
		{0,0,1},
		{1,1,1},
	},
	{ // 6
		{1,1,1},
		{1,0,0},
		{1,1,1},
		{1,0,1},
		{1,1,1},
	},
	{ // 7
		{1,1,1},
		{0,0,1},
		{0,0,1},
		{0,0,1},
		{0,0,1},
	},
	{ // 8
		{1,1,1},
		{1,0,1},
		{1,1,1},
		{1,0,1},
		{1,1,1},
	},
	{ // 9
		{1,1,1},
		{1,0,1},
		{1,1,1},
		{0,0,1},
		{1,1,1},
	},
};

vector<int> candidates(int idx) {
	vector<int> ret;
	for (int i = 0; i < 10; ++i) {
		bool flag = true;

		for (int j = 0; j < 5 && flag; ++j) {
			for (int k = 0; k < 3 && flag; ++k) {
				if (on[j][k + idx] && !NUMBERS_SHAPE[i][j][k])
					flag = false;
			}
		}

		if (flag)
			ret.push_back(i);
	}
	return ret;
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
#endif

	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	cin >> n;

	for (int i = 0; i < 5; ++i) {
		for (int j = 0; j < 4 * n - 1; ++j) {
			char ch;
			cin >> ch;

			on[i][j] = (ch == '#');
		}
	}

	vector<vector<int>> cands;
	for (int i = 0; i < 4 * n - 1; i += 4) {
		cands.push_back(candidates(i));
	}

	for (auto& v : cands) {
		if (v.empty()) {
			cout << -1 << '\n';
			return 0;
		}
	}

	double avg = 0;
	int exp = 1;
	for (auto rit = cands.rbegin();
		rit != cands.rend();
		++rit, exp *= 10) {
		avg += (accumulate(rit->begin(), rit->end(), 0) / (double)rit->size()) * exp;
	}

	cout << fixed << setprecision(6) << avg << '\n';

	return 0;
}

저는 bool로 변환하고 이것저것 삽질을 좀 해놨는데 그냥 문자열 비교로 하는게 편합니다.

문제에 주어지는 0~9 그거 복사해서 char 2차원 배열로 만들고 그걸로 비교하세요.

반응형

'Online Judge > 백준' 카테고리의 다른 글

[백준][C++] 2671: 잠수함식별  (0) 2020.07.05
[백준][C++] 2866: 문자열 잘라내기  (0) 2020.07.04
[백준][C++] 4836: 춤  (0) 2020.07.02
[백준][C++] 1043: 거짓말  (0) 2020.06.29
[백준][C++] 1036: 36진수  (0) 2020.06.24