1. 程式人生 > 實用技巧 >十字繡

十字繡

題目描述

考古學家發現了一塊布,布上做有針線活,叫做“十字繡”,即交替地在布的兩面穿線。

布是一個\(n*m\)的網格,線只能在網格的頂點處才能從布的一面穿到另一面。每一段線都覆蓋一個單位網格的兩條對角線之一,而在繡的過程中,一針中連續的兩段線必須分處布的兩面。並且每一段線只能走一次。

給出布兩面的圖案,問最少需要幾針才能繡出來?一針是指標不離開布的一次繡花過程。

輸入格式

第1行兩個數\(N\)\(M\)

接下來\(N\)行每行\(M\)個數描述正面。

再接下來\(N\)行每行\(M\)個數描述反面。

每個格子用.(表示空),\(/\)(表示從右上角連到左下角),\(\$(表示從左上角連到右下角)和\)

X$(表示連兩條對角線)表示。

輸出格式

一個數,最少要用的針數。

樣例

樣例輸入

4 5
.....
.\...
..\..
.....
.....
....\ 
.\X..
.....

樣例輸出

4

(為使輸入資料更直觀,樣例為圖片格式,下面是文字格式的樣例)

資料範圍與提示

對於100%的資料,\(1<=n,m<=200\)

code

#include <bits/stdc++.h>
using namespace std;
const int maxn = 200 + 10;
char c[maxn];
int s, n, m;
int h[maxn][maxn];
struct node {
    int t, next;
} e[maxn * maxn * 8];
int head[maxn * maxn], f[maxn * maxn], jl[maxn * maxn];
int near[maxn * maxn];
int v[maxn * maxn];
int tot = 0;
void add(int x, int y, int z) {
    f[x] = 1;
    e[++tot] = (node){ y, head[x] };
    head[x] = tot;
    if (z == 1)
        jl[x]++;
    else
        near[x]++;
}
void add1(int x, int y, int k) {
    add(h[x][y + 1], h[x + 1][y], k);
    add(h[x + 1][y], h[x][y + 1], k);
}
void add2(int x, int y, int k) {
    add(h[x][y], h[x + 1][y + 1], k);
    add(h[x + 1][y + 1], h[x][y], k);
}
void read(int k) {
    for (int i = 1; i <= n; i++) {
        scanf("%s", c + 1);
        for (int j = 1; j <= m; j++)
            if (c[j] == 'X')
                add1(i, j, k), add2(i, j, k);
            else if (c[j] == '/')
                add1(i, j, k);
            else if (c[j] == '\\')
                add2(i, j, k);
    }
}
void dfs(int x) {
    v[x] = 1;
    s += abs(jl[x] - near[x]);
    for (int i = head[x]; i; i = e[i].next)
        if (!v[e[i].t])
            dfs(e[i].t);
}

int main() {
    cin >> n >> m;
    for (int i = 1; i <= n + 1; i++)
        for (int j = 1; j <= m + 1; j++) h[i][j] = (i - 1) * (m + 1) + j;
    read(1);
    read(-1);
    int ans = 0;
    for (int i = 1; i <= n + 1; i++)
        for (int j = 1; j <= m + 1; j++) {
            int x = h[i][j];
            if (!f[x] || v[x])
                continue;
            s = 0;
            dfs(x);
            if (s == 0)
                s = 1;
            else if (s != 0)
                s = s / 2;
            ans += s;
        }
    cout << ans;
    return 0;
}