프로그래밍 문제를 풀다가 보면, 간혹 특정 라이브러리 함수를 사용하지 못하게 하는 경우가 있습니다.

(삼성전자 SW Expert Academy에서 보는 상시 SW 역량 테스트 B형 문제라던지...)


이러한 경우 로컬에서 디버깅을 위해서 printf 함수 등을 사용하다가 제출 할 때에는 이 함수들을 다 제거를 해야 하는데, 이러한 일들이


엄청 귀찮게 되는 경우가 있는데 이러한 귀찮음을 없애줄 수 있는 전처리문 코드를 공유합니다.




 

#ifdef WIN32
#define log(...) printf(__VA_ARGS__)
#else
#define log(...) (void)0
#endif


위와 같은 코드를 소스코드 파일 상단에 추가를 해 놓으면 log라는 함수를 이용해서 printf 함수 기능을 사용할 수 있습니다.


윈도우즈 환경에서는 printf 기능이 잘 동작하게 되고, 제출을 할 경우 (일반적으로 서버는 리눅스 환경인 경우가 많으므로), log 함수들이 (void)0으로 치환


되게 되므로 아무런 동작을 하지 않게 됩니다.


아니면 제출할 경우에만 #define 구문을 상황에 맞게 주석 처리를 하면, 엄청나게 남발해놓은 printf함수를 한두줄 코드 바꾸는 것으로 모두


비활성화 하거나 활성화 할 수 있습니다.


log함수는 printf함수와 동일하게 인자를 넣어서 필요한 시기에 호출하면 됩니다.

백준저지 3090번 문제 '차이를 최소로' 문제 풀이입니다.

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


인접한 수의 최대 차이값을 c라고 할때, 이 c를 최소로 만들어야 한다.


최대값의 최소값을 바로 구하기는 힘드므로 문제를 조금 변형한다.


인접한 수의 최대 차이값을 최소로 하는 값은 무엇인가 => '인접한 수의 최대 차이값을 c 값으로 만들 수 있는가(Y/N)'



또한 만약 최대 차이값을 c값으로 만들 수 있다면, c+1 으로도 물론 만들 수 있을 것이다. 이러한 특성을 이용하여


바이너리 서치로 문제를 해결할 수 있다.




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

#define MN 100005
int n, T;
int a[MN];
int L[MN], R[MN];
bool ok(int v) {
    R[0]=a[0];
    L[n-1]=a[n-1];
    for (int i=1;i<n;i++) R[i] = min(R[i-1]+v, a[i]);
    for (int i=n-2;i>=0;i--) L[i] = min(L[i+1]+v, a[i]);
    long long inv = 0;
    for (int i=0;i<n;i++) inv += a[i] - min(L[i],R[i]);
    return inv <= T;
}
void ans(int v) {
    R[0]=a[0];
    L[n-1]=a[n-1];
    for (int i=1;i<n;i++) R[i] = min(R[i-1]+v, a[i]);
    for (int i=n-2;i>=0;i--) L[i] = min(L[i+1]+v, a[i]);
    for (int i=0;i<n;i++) {
        int s = a[i]-min(L[i],R[i]);
        printf("%d ", a[i] - s);
    }
}
int main() {
    cin >> n >> T;
    for (int i=0; i < n; i++) {
        scanf("%d", a+i);
    }
    int l = 0, r = MN;
    while (l < r) {
        int m = (l + r) / 2;
        if (ok(m)) r = m;
        else l = m + 1;
    }
    ans(r);
}



ok 함수에서 인접 수 차이 최대값이 v이도록, T번의 감소 연산으로 가능한지 여부를 리턴해준다.


main문의 while문에서 바이너리 서치를 수행하고, 인접수 차이 최대값의 최소값이 r이 되므로,


해당 값이 되도록 감소시킨 배열 값을 ans함수에서 출력해준다.


이제 여기서 T번의 감소 연산으로 가능한지 여부는 O(N)로 체크를 한다.


어차피 감소하는 연산만 가능하므로, 인접 수 차이가 c값이 되도록, 상한선을 R[i] + c 로 정하고, 다음 값이 그 값보다 작으면 그 작의 상한선이 더 낮을 예정이므로 최소값을 취하면서 좌우로 상한선을 체크한다.


더 낮은 상한선을 기준으로 그 값을 초과하는 것들을 다 감소시켜야 한다. 그 감소시켜야 하는 값들이 T 개수 보다 많다면 불가능하다.

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


백준저지 1261번 문제인 알고스팟 풀이입니다.


벽을 몇개를 부숴야 하는지를 알아야 하므로, 벽을 부술 때 만 값을 1 증가시키는 식으로 BFS를 합니다.


다만, 벽을 부수지 않는 경우들을 우선적으로 처리하도록 하기 위해서 큐 대신 우선순위 큐(벽 부순 값이 낮은 것 부터 리턴하도록 Min Heap 사용)를 활용


합니다.



 

#include <iostream>
#include <queue>
#include <string>
using namespace std;

string map[101];
struct State {
	int val, x, y;
	bool operator<(const struct State& rhs) const {
		return val > rhs.val;
	}
};
const int dx[] = { +1, +0, +0, -1 };
const int dy[] = { +0, +1, -1, +0 };
bool v[101][101];
int main() {
#ifdef WIN32
	freopen("in.txt", "r", stdin);
#endif
	int M, N;
	cin >> M >> N;
	for (int i = 0; i < N; i++) {
		cin >> map[i];
	}
	priority_queue<State> pq;
	pq.push({ 0, 0, 0 });

	while (pq.size()) {
		auto cur = pq.top();
		pq.pop();
		if (cur.x == N - 1 && cur.y == M - 1) {
			cout << cur.val << endl;
			return 0;
		}
		for (int i = 0; i < 4; i++) {
			int nx = cur.x + dx[i];
			int ny = cur.y + dy[i];
			if (nx < 0 || ny < 0 || nx >= N || ny >= M) continue;
			if (v[nx][ny]) continue;
			v[nx][ny] = 1;
			pq.push({ cur.val + (map[nx][ny] == '1' ? 1 : 0 ), nx, ny });
		}
	}
}


두번째 풀이법으로는 비슷한 방식이나 구현이 조금 다릅니다.


벽을 부수지 않고 이동할 수 있는 공간을 하나의 큰 정점으로 그룹핑합니다. 


N, M좌표에서 먼저 큰 정점으로 만들어서 2로 마킹하고, 정점간 이동으로 BFS 탐색을 하면서 2로 마킹된 정점을 찾습니다.


정점간 이동은 벽을 하나 부수는 것과 같이 동작하므로 최소 부수는 벽의개수를 알 수 있게 됩니다.



 

#include <iostream>
#include <queue>
#include <string>
#include <vector>
#include <cstring>
using namespace std;

string map[101];
struct State {
	int val, x, y;
};
struct Pos {
	int x, y;
};
const int dx[] = { +1, +0, +0, -1 };
const int dy[] = { +0, +1, -1, +0 };
bool v[101][101];
int M, N;
vector<Pos> edges[101][101];
void bfs(int sx, int sy) {
	memset(v, 0, sizeof(v));
	queue<Pos> q;
	q.push({ sx, sy });
	v[sx][sy] = 1;
	while (q.size()) {
		auto c = q.front(); q.pop();
		if ((map[c.x][c.y] == '1' || map[c.x][c.y] == '2') && !(c.x == sx && c.y == sy)) {
			edges[sx][sy].push_back({ c.x, c.y });
		}
		else {
			for (int i = 0; i < 4; i++) {
				int nx = c.x + dx[i];
				int ny = c.y + dy[i];
				if (nx < 0 || ny < 0 || nx >= N || ny >= M) continue;
				if (v[nx][ny]) continue;
				v[nx][ny] = 1;
				q.push({ nx, ny });
			}
		}
	}
}
void dfs(int x, int y) {
	v[x][y] = 1;
	map[x][y] = '2';
	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		if (nx < 0 || ny < 0 || nx >= N || ny >= M) continue;
		if (v[nx][ny]) continue;
		if (map[nx][ny] == '1') {
			continue;
		}
		map[nx][ny] = '2';
		dfs(nx, ny);
	}
}
int main() {
#ifdef WIN32
	freopen("in.txt", "r", stdin);
#endif

	cin >> M >> N;
	for (int i = 0; i < N; i++) {
		cin >> map[i];
	}

	dfs(N - 1, M - 1);
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			bfs(i, j);
		}
	}
	memset(v, 0, sizeof(v));
	
	queue<State> q;
	q.push({ 0, 0, 0 });
	v[0][0] = 1;
	if (map[0][0] == '2') {
		cout << 0 << endl;
		return 0;
	}

	while (q.size()) {
		auto c = q.front(); q.pop();
		for (auto n : edges[c.x][c.y]) {
			if (v[n.x][n.y]) continue;
			v[n.x][n.y] = 1;
			if (map[n.x][n.y] == '2') {
				cout << c.val << endl;
				return 0;
			}
			q.push({ c.val + 1, n.x, n.y });
		}
	}
	
}


백준저지 2517 달리기 문제 풀이입니다.


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


Counting Inversions 문제와 유사한 문제입니다.


풀이는 백준 10090번 문제 Counting Inversions를 참조하면 좋습니다.



 

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
pii A[500005];
pii T[500005];
int ans[500005];

void merge(int s, int m, int e) {
    int p1 = s;
    int p2 = m;
    int k = s;
    while (p1 < m && p2 < e) {
        if (A[p1].first <= A[p2].first) {
            T[k++] = A[p1++];
        } else {
            int advance = p1 - s;
            int origin_rank = A[p2].second;
            if (advance) {
                ans[origin_rank] -= advance;
                /*
                printf("%d의 원래 순위는 %d이고, %d개를 앞지를 수 있다.\n", A[p2].first, origin_rank, advance);
                for (int i=s; i < p1; i++) {
                    printf("\t%d를 앞지른다.\n", A[i]);
                } 
                */
            }
            T[k++] = A[p2++];
        }
    }
    
    while (p1 < m) {
        T[k++] = A[p1++];
    }
    
    while (p2 < e) {
        int advance = p1 - s;
        int origin_rank = A[p2].second;
        if (advance) {
            ans[origin_rank] -= advance;
            /*
            printf("%d의 원래 순위는 %d이고, %d개를 앞지를 수 있다.\n", A[p2].first, origin_rank, advance);
            for (int i=s; i < p1; i++) {
                printf("\t%d를 앞지른다.\n", A[i]);
            } 
            */
        }
        T[k++] = A[p2++];
    }
    
    for (int i=s; i < e; i++) {
        A[i] = T[i];
    }
    
}

void merge_sort(int s, int e)  {
    int m = (s + e) / 2;
    if (s < m) {
        merge_sort(s, m);
        merge_sort(m, e);
        merge(s, m, e);
    }
}
int main() {
    int n;
    scanf("%d", &n);
    
    for (int i=1; i <= n; i++) {
        scanf("%d", &A[i].first);
        A[i].second = i;
        ans[i] = i;
    }
    
    merge_sort(1, n+1);
    
    for (int i=1; i <= n; i++) {
        printf("%d\n", ans[i]);
    }
	return 0;
}




백준저지 16236번 아기 상어 문제 풀이입니다.

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


N값이 작으므로 bfs를 활용한 완전탐색으로 하나하나 시뮬레이션 해서 풀면 됩니다.



#include <stdio.h> #include <queue> #include <vector> #include <cstring> #include <algorithm> using namespace std; const int dx[] = { +1, -1, +0, +0 }; const int dy[] = { +0, +0, +1, -1 }; int n; struct Pos { int x, y; bool operator<(const struct Pos& rhs) const { return x != rhs.x ? x < rhs.x : y < rhs.y; } bool operator>(const struct Pos& rhs) const { return x != rhs.x ? x > rhs.x : y > rhs.y; } }; typedef pair<int, Pos> State; //first -> 먹는데 걸리는 거리 / second->좌표 vector<State> eatable; int field[21][21]; bool visit[21][21]; int shark_size, eat_left; inline bool is_in(int x, int y) { return x >= 0 && y >= 0 && x < n && y < n; } #define FOR(i, a, b) for (int i=a; i < b; i++) void bfs(int x, int y) { visit[x][y] = true; queue<State> q; q.push({ 0, { x, y } }); while (!q.empty()) { State s = q.front(); q.pop(); for (int i = 0; i < 4; i++) { int nx = s.second.x + dx[i]; int ny = s.second.y + dy[i]; int d = s.first; if (is_in(nx, ny)) { auto& f = field[nx][ny]; auto& v = visit[nx][ny]; if (!v) { //방문 안한 경우 v = true; if (f <= shark_size) { q.push({ d + 1, { nx, ny } }); if (f > 0 && f < shark_size) { eatable.push_back({ d + 1, { nx, ny } }); } } } } } } } int main() { #ifdef WIN32 freopen("input.txt", "r", stdin); #endif scanf("%d", &n); Pos shark; shark_size = 2; eat_left = 2; int ans = 0; //get input FOR(i, 0, n) { FOR(j, 0, n) { scanf("%d", &field[i][j]); if (field[i][j] == 9) { shark.x = i; shark.y = j; field[i][j] = 0; } } } while (true) { memset(visit, 0, sizeof(visit)); eatable.clear(); bfs(shark.x, shark.y); sort(eatable.begin(), eatable.end()); if (eatable.size() == 0) break; int distance = eatable[0].first; int nx = eatable[0].second.x; int ny = eatable[0].second.y; shark.x = nx; shark.y = ny; field[nx][ny] = 0; --eat_left; if (eat_left <= 0) { shark_size++; eat_left = shark_size; } ans += distance; } printf("%d\n", ans); }


백준저지 16235번 나무 재테크 문제 풀이입니다.

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


전형적인 구현 문제입니다.


벡터의 2차원 배열로 나무들을 표현했고, 나무의 나이를 매년 더하기 보다는, 사람 나이를 생년월일로 나타내듯,


탄생 년도와 현재 년도를 기준으로 나이를 표현해서 풀이해 보았습니다.



#include <iostream> #include <cstdio> #include <vector> #include <algorithm> #include <functional> using namespace std; vector<int> birth[10][10]; int V[10][10]; //현재 양분 int A[10][10]; //추가하는 양분 int B[10][10]; //나무 죽어서 추가하는 양분 int n, m, k; const int dx[] = { +1, +1, +1, +0, +0, -1, -1, -1 }; const int dy[] = { +1, +0, -1, +1, -1, +1, +0, -1 }; inline bool is_in(int x, int y) { return x >= 0 && y >= 0 && x < n && y < n; } #define FOR(i, a, b) for (int i=a; i < b; i++) int main() { scanf("%d%d%d", &n, &m, &k); FOR(i, 0, n) { FOR(j, 0, n) { scanf("%d", &A[i][j]); V[i][j] = 5; } } FOR(i, 0, m) { int x, y, age; scanf("%d%d%d", &x, &y, &age); x--; y--; birth[x][y].push_back(-age); } FOR(year, 0, k) { //봄 //나이 = year - birth //양분 먹음, 죽을 나무 결정 FOR(i, 0, n) { FOR(j, 0, n) { if (birth[i][j].size()) { sort(birth[i][j].begin(), birth[i][j].end(), greater<int>()); int death_count = 0; FOR(l, 0, birth[i][j].size()) { int age = year - birth[i][j][l]; if (V[i][j] >= age) { V[i][j] -= age; } else { death_count++; B[i][j] += age / 2; } } FOR(l, 0, death_count) { birth[i][j].pop_back(); } } } } //여름 //나이 = year - birth + 1; FOR(i, 0, n) { FOR(j, 0, n) { V[i][j] += B[i][j] + A[i][j]; B[i][j] = 0; if (birth[i][j].size()) { FOR(l, 0, birth[i][j].size()) { int age = year - birth[i][j][l] + 1; if (age % 5 == 0) { FOR(d, 0, 8) { int nx = i + dx[d]; int ny = j + dy[d]; if (is_in(nx, ny)) { birth[nx][ny].push_back(year); } } } } } } } } int ans = 0; FOR(i, 0, n) { FOR(j, 0, n) { ans += birth[i][j].size(); } } printf("%d\n", ans); }


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


백준저지 10090번 문제 Counting Inversions라는 문제이다.


나름 유명한 문제라고 한다.


수열이 있을때 자신보다 앞에있는 숫자 중에 자신보다 큰 녀석을 Inversion이라고 하는데 그 Inversion의 개수를 구하는 문제이다.


Brute force로 풀면 //(O(N^2)//)로 풀게 되는데 그럴 경우 당연 TLE가 나게 된다. 이보다 효율적인 알고리즘이 필요하다.




이 문제는 Merge sort를 응용해서 풀 수 있다.


Merge sort에서 Merge를 수행할 때, 인접한 왼쪽 부분배열과 오른쪽 부분배열을 Merge 할 것이다.


Merge 하기 직전에 왼쪽 부분배열의 모든 원소는 오른쪽 부분배열의 모든 원소보다 원래 왼쪽에 있었다는 것은 자명하다.


그래서 Merge를 할때 오른쪽 배열에 있는 원소가 임시 배열로 들어갈 때, 왼쪽 배열에서 아직 임시 배열에 들어가지 않은 경우


왼쪽배열에 아직 남아있는 원소는 방금 들어간 오른쪽 배열에 있던 원소보다는 다 크기가 크다는 이야기가 된다.


고로 Merge Sort응용으로 //(O(NlgN)//)으로 풀 수 있다.



 

#include <stdio.h>
#include <malloc.h>

int arr[1000005];
int tmp[1000005];

typedef long long ll;
ll ans;
void merge(int start, int mid, int end) { // [start, mid) [mid, end)
    int p1, p2, index = 0;
    p1 = start;
    p2 = mid;
    while (p1 < mid && p2 < end) {
        if (arr[p1] < arr[p2]) {
            tmp[index++] = arr[p1++];
        }
        else if (arr[p1] > arr[p2]) {
            ans += mid - p1;
            tmp[index++] = arr[p2++];
        }
        else {
            tmp[index++] = arr[p2++];
        }
    }
    while (p1 < mid) {
        tmp[index++] = arr[p1++];
    }
    while (p2 < end) {
        tmp[index++] = arr[p2++];
    }
    for (int i = 0; i < end - start; ++i) {
        arr[start + i] = tmp[i];
    }
}

void merge_sort(int start, int end) { // [start, end)
    int mid = (start + end) / 2;
    if (start < mid) {
        merge_sort(start, mid);
        merge_sort(mid, end);
        merge(start, mid, end);
    }    
}

int main() {

    ans = 0;
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) {
        scanf("%d", arr + i);
    }

    merge_sort(0, n);
    printf("%lld\n", ans);

    return 0;
}



Reference

https://www.geeksforgeeks.org/counting-inversions/

백준저지 10828번 스택 문제 풀이입니다.

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


배열을 넉넉하게 잡아서 메모리를 할당하고, 간단하게 구현할 수 있습니다.


 

#include <bits/stdc++.h>
using namespace std;
int arr[10001];
int size;
inline void push(int a) {
    arr[size++] = a;
}
inline int pop() {
    return size > 0 ? arr[--size] : -1;
}
inline int top() {
    return size > 0 ? arr[size-1] : -1;
}
inline int empty() {
    return size>0 ? 0 : 1;
}
inline int sz() {
    return size;
}
int main() {
    int n;
    cin >> n;
    while(n--) {
        string cmd;
        cin >> cmd;
        if (cmd == "push") {
            int tmp;
            cin >> tmp;
            push(tmp);
        } else if (cmd == "pop") {
            cout << pop() << '\n';
        } else if (cmd == "size") {
            cout << sz() << '\n';
        } else if (cmd == "empty") {
            cout << empty() << '\n';
        } else if (cmd == "top") {
            cout << top() << '\n';
        }
    }
    return 0;
}



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


백준저지 14891번 문제 톱니바퀴 문제 풀이이다.


시뮬레이션 문제이다. 톱니바퀴가 도는 모습을 하나하나 따라가면 된다.


회전하는 경우를 어떻게 구현할 것인가가 관건인데, 12시 방향에 있는 좌표를 저장하는 방식으로 하였다.


Cyclic하게 회전하므로 방향 개수로 Modular 연산을 통해서 cyclic한 형태를 구현할 수 있다.




 

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

int gear[4][8];
int pos[4]; //12시 방향을 의미함. ++하면 반시계, --하면 시계방향 회전
int rot_delta[4];
int get_polar(int num, int clock) {
    int base = pos[num] + clock;
    if (base >= 8) {
        base = base % 8;
    }
    while (base < 0) {
        base += 8;
    }
    return gear[num][base];
}
int main() {
    for (int i=0; i < 4; i++) {
        for (int j=0; j < 8; j++) {
            scanf("%1d", &gear[i][j]);
        }
    }
    
    int rot;
    cin >> rot;
    for (int i=0; i < rot; i++) {
        int num, dir;
        cin >> num >> dir;
        num--;
        rot_delta[num] = dir; //현재꺼 회전량 저장
        
        int prev = num;
        int cur = prev + 1;
        int prev_dir = dir;
        while (cur < 4) {
            if (get_polar(prev, 2) == get_polar(cur, 6)) break;
            rot_delta[cur] = -prev_dir;
            prev_dir = -prev_dir;
            prev = cur;
            cur++;
        }
        prev = num;
        cur = prev - 1;
        prev_dir = dir;
        while (cur >= 0) {
            if (get_polar(prev, 6) == get_polar(cur, 2)) break;
            rot_delta[cur]  = -prev_dir;
            prev_dir = -prev_dir;
            prev = cur;
            cur--;
        }
        
        for (int j=0; j < 4; j++){
            pos[j] -= rot_delta[j];
            rot_delta[j] = 0;
        }
            
    }
    int ans = 0;
    ans += (get_polar(0, 0) == 0 ? 0 : 1);
    ans += (get_polar(1, 0) == 0 ? 0 : 2);
    ans += (get_polar(2, 0) == 0 ? 0 : 4);
    ans += (get_polar(3, 0) == 0 ? 0 : 8);
  
    
    cout << ans << endl;
	return 0;
}




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


백준 14890번 문제 경사로 풀이이다.


구현 문제인데, 어떻게 하면 효율적으로 풀 지 고민을 해 보았다.


만약 경사로가 다음과 같이 나타난다면 다음과 같은 자료구조로 변환하여 문제를 풀이하였다.


1 1 1 1 2 2 3 3 3 3 3


만약 위와 같은 형태로 경사로가 구성되어 있다면, 1이 4개 2가 2개 3이 5개이므로 다음과 같은 형태로 저장한다.

(1, 4) (2, 2) (3, 5)


경사로를 놓는데에 L의 길이가 필요하다면, 낮은 위치에 길이를 L만큼 제외하고 음수가 되게 되면 실패한다고 생각하였다.



 

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

int field[105][105];
int road[105];
typedef pair<int, int> pii;
int main() {
    int n;
    int l;
    cin >> n >> l;
    int ans = 0;
    for (int i=1; i <= n; i++) {
        for (int j=1;j <= n; j++) {
            cin >> field[i][j];
        }
    }
    
    //garo check
    vector<pii> arr; //값, 연속개수
    for (int i=1; i <= n; i++) {
        arr.clear();
        int prev = field[i][1];
        int prev_num = 1;
        for (int j=2; j <= n ;j++) {
            auto& cur = field[i][j];
            if (cur != prev) {
                arr.push_back(make_pair(prev, prev_num));
                prev_num = 0;
            }
            prev_num++;
            prev = cur;
        }
        arr.push_back(make_pair(prev, prev_num));

        bool correct = true;
        for (int k=1; k < (int)arr.size(); k++) {
            auto& p_height = arr[k-1].first;
            auto& p_length = arr[k-1].second;
            auto& c_height = arr[k].first;
            auto& c_length = arr[k].second;
            int delta = p_height - c_height;
            if (delta*delta > 1) {
                correct = false;
                break;
            }
            if (p_height == c_height+1) {
                c_length -= l;
                if (c_length < 0) {
                    correct = false;
                }
            } else if (p_height+1 == c_height) {
                p_length -= l;
                if (p_length < 0) {
                    correct = false;
                }
            }
        }
        
        if (correct) {
            ans++;
        }
    }
    
    //sero check
    for (int i=1; i <= n; i++) {
        arr.clear();
        int prev = field[1][i];
        int prev_num = 1;
        for (int j=2; j <= n ;j++) {
            auto& cur = field[j][i];
            if (cur != prev) {
                arr.push_back(make_pair(prev, prev_num));
                prev_num = 0;
            }
            prev_num++;
            prev = cur;
        }
        arr.push_back(make_pair(prev, prev_num));

        bool correct = true;
        for (int k=1; k < (int)arr.size(); k++) {
            auto& p_height = arr[k-1].first;
            auto& p_length = arr[k-1].second;
            auto& c_height = arr[k].first;
            auto& c_length = arr[k].second;
            int delta = p_height - c_height;
            if (delta*delta > 1) {
                correct = false;
                break;
            }
            if (p_height == c_height+1) {
                c_length -= l;
                if (c_length < 0) {
                    correct = false;
                }
            } else if (p_height+1 == c_height) {
                p_length -= l;
                if (p_length < 0) {
                    correct = false;
                }
            }
        }
        
        if (correct) {
            ans++;
        }
    }
    
    cout << ans << endl;
    
	return 0;
}




+ Recent posts