#include <stdio.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
static int idSel;
static int unionCnt;
class Country {
public:
int id;
int people;
public:
Country() {
id = -1;
people = 0;
idSel = 0;
unionCnt = 0;
}
void setId(int _id) {
id = _id;
}
int getId() {
return id;
}
void setPeople(int _people) {
people = _people;
}
int getPeople() {
return people;
}
bool isUnion(Country &cntr, const int L, const int R) {
if(getPeople() >= cntr.getPeople()){
if (getPeople() - cntr.getPeople() >= L &&
getPeople() - cntr.getPeople() <= R) {
return true;
}
}
else if(getPeople() <= cntr.getPeople()){
if (cntr.getPeople() - getPeople() >= L &&
cntr.getPeople() - getPeople() <= R) {
return true;
}
}
return false;
}
void unionCountry(Country &cntr) {
if(cntr.getId() == -1){
//상대국이 어디에도 소속되어있지 않니?
if (getId() == -1) {
//자신이 어디에도 소속되어있지 않니?
//cout << "상대국과 자신이 어디에도 소속되어있지 않니?" << endl;
cntr.setId(idSel);
setId(idSel);
idSel++;
}
else {
//상대국이 소속되지 않고 자신은 소속되있니?
cntr.setId(getId());
}
}
else {
//상대국이 소속되어있니?
if (getId() == -1) {
//자신이 어디에도 소속되어있지 않니?
setId(cntr.getId());
}
else {
//상대국과 자신 둘 다 소속되었니?
if (getId() < cntr.getId()) {
cntr.setId(getId());
}
else {
setId(cntr.getId());
}
//더 작은 id에 통합
}
}
}
};
int main(void) {
int N, L, R;
int result = 0;
//L이상 R이하
cin >> N;
cin >> L;
cin >> R;
//차이값
Country **map = new Country*[N];
for (int i = 0; i < N; i++) {
map[i] = new Country[N];
}
//맵 생성 완료
int num;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cin >> num;
map[i][j].setPeople(num);
}
}
//인구 수 조절
enum { UP, LEFT, RIGHT, DOWN };
const int MAX_ARR = N - 1;
//이동 횟수
vector<pair<int, int> > idList;
int cnt = 0;
int **idMap = new int*[N];
for (int i = 0; i < N; i++) {
idMap[i] = new int[N];
}
//아이디 맵 생성
int **peopleMap = new int*[N];
for (int i = 0; i < N; i++) {
peopleMap[i] = new int[N];
}
//people 맵 생성
bool isEqual = false;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
idMap[i][j] = -1;
peopleMap[i][j] = -1;
}
}
while (true) {
while (true) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
//cout << i << ',' << j << " 비교" << endl;
if (i > 0) {
if (map[i][j].isUnion(map[i - 1][j], L, R)) {
//윗칸이 만약 연합국 대상이냐?
map[i][j].unionCountry(map[i - 1][j]);
}
}
//위에 확인
if (j > 0) {
if (map[i][j].isUnion(map[i][j - 1], L, R)) {
//왼쪽이 만약 연합국 대상이냐?
map[i][j].unionCountry(map[i][j - 1]);
}
}
//왼쪽 확인
if (j < MAX_ARR) {
if (map[i][j].isUnion(map[i][j + 1], L, R)) {
//오른쪽이 만약 연합국 대상이냐?
map[i][j].unionCountry(map[i][j + 1]);
}
}
//오른쪽 확인
if (i < MAX_ARR) {
if (map[i][j].isUnion(map[i + 1][j], L, R)) {
//아래가 만약 연합국 대상이냐?
map[i][j].unionCountry(map[i + 1][j]);
}
}
//아래 확인
}
}
isEqual = false;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (map[i][j].getId() != idMap[i][j]) {
isEqual = true;
goto label;
}
}
}
//아이디 맵과 수정 후 맵이 같은지 비교
label:
if (!isEqual) break;
//만약 같으면 id 값 부여 끝.
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
idMap[i][j] = map[i][j].getId();
}
}
//id map 값을 대입함
}
////출력 화면
//cout << endl;
//for (int i = 0; i < N; i++) {
// for (int j = 0; j < N; j++) {
// cout << map[i][j].getPeople() << '(' << map[i][j].getId() << ')' << ' ';
// }
// cout << endl;
//}
////출력화면
for (int i = 0; i < idSel; i++) {
idList.push_back(pair<int, int>(0, 0));
}
//id갯수만큼 공간넓힘
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (map[i][j].getId() != -1) {
idList[map[i][j].getId()].second += map[i][j].getPeople();
idList[map[i][j].getId()].first++;
}
}
}
//id에 해당하는 값 누적
if (idList.size() > 0) {
result++;
for (int i = 0; i < idList.size(); i++) {
for (int j = 0; j < N; j++) {
for (int k = 0; k < N; k++) {
//if (map[j][k].getId() != -1 && idList[i].first != int(0) && idList[i].second != int(0)) {
/*cout << "i is " << i << endl;
cout << "idList[i].first : " << idList[i].first << endl;
cout << "idList[i].second : " << idList[i].second << endl;*/
if(map[j][k].getId() == i) map[j][k].setPeople(idList[i].second / idList[i].first);
//}
}
}
}
}
//인구 이동
idList.clear();
isEqual = false;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (map[i][j].getPeople() != peopleMap[i][j]) {
isEqual = true;
goto label2;
}
}
}
//피플 맵과 수정 후 맵이 같은지 비교
label2:
if (!isEqual) { break; }
//만약 같으면 피플 값 부여 끝.
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
peopleMap[i][j] = map[i][j].getPeople();
}
}
//피플 map 값을 대입함
idSel = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
map[i][j].setId(-1);
}
}
//id 초기화
}
//연합국 생성
cout << result;
//system("pause");
return 0;
}
'코딩테스트 문제풀이' 카테고리의 다른 글
[프로그래머스, javascript]쿼드 압축 후 개수 세기 (0) | 2021.03.19 |
---|---|
[백준 16235] 나무 재테크 (0) | 2019.10.12 |
[백준 1969] DNA (0) | 2019.10.12 |
[백준 1026] 보물 (0) | 2019.10.12 |
[백준 1439] 문제 풀기 (그리디) (0) | 2019.07.08 |