CF1344B Monopole Magnets

题目链接:https://codeforces.com/contest/1345

 

 

 

 

想法:

每一行每一列必须要有一个S的磁铁,我们考虑放置 S 磁铁的方法。

如果某一行或者某一列有黑块的存在那么它一定可以到这行或者这列的 S 磁铁的位置

所以 我们得到一个结论: 如果某个位置可以放置 S 磁铁,那么假设这个位置是 (x,y)  那么 左边 -> (x,y)  右边 -> (x,y)  上边 -> (x,y)  下边 -> (x,y) 的黑块必须是“连续”的

我们预处理出 从行首、行位、列首、列尾各有多少块黑色方块,然后判断一下即可。

 

#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <ctime>
#include <bitset>
#include <cmath>
#include <sstream>
#include <iostream>
#include <unordered_map>

#define ll long long
#define ull unsigned long long
#define ls nod<<1
#define rs (nod<<1)+1
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define INF 0x3f3f3f3f3f3f3f3f
#define max(a, b) (a>b?a:b)
#define min(a, b) (a<b?a:b)


const double eps = 1e-10;
const int maxn = 1e3 + 10;
const ll MOD = 99999999999999;

int sgn(double a) { return a < -eps ? -1 : a < eps ? 0 : 1; }

using namespace std;

char s[maxn][maxn];
int vis[maxn][maxn];
int l1[maxn][maxn],l2[maxn][maxn],h1[maxn][maxn],h2[maxn][maxn];
int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
int n,m;
int row[maxn],col[maxn];

void dfs(int x,int y) {
    for (int i = 0;i < 4;i++) {
        int x1 = x + dir[i][0],y1 = y + dir[i][1];
        if (x1 >= 1 && x1 <= n && y1 >= 1 && y1 <= m && !vis[x1][y1] && s[x1][y1] == '#') {
            vis[x1][y1] = 1;
            dfs(x1,y1);
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for (int i = 1;i <= n;i++) {
        for (int j = 1;j <= m;j++) {
            cin >> s[i][j];
        }
    }
    int cnt = 0;
    for (int i = 1;i <= n;i++) {
        for (int j = 1;j <= m;j++) {
            if (s[i][j] == '#' && !vis[i][j]) {
                vis[i][j] = 1;
                dfs(i,j);
                cnt++;
            }
            if (s[i][j] == '#' && s[i-1][j] != '#')
                l1[i][j] = l1[i-1][j] + 1;
            else
                l1[i][j] = l1[i-1][j];
            if (s[i][j] == '#' && s[i][j-1] != '#')
                h1[i][j] = h1[i][j-1] + 1;
            else
                h1[i][j] = h1[i][j-1];
        }
    }
    for (int i = n;i >= 1;i--) {
        for (int j = m;j >= 1;j--) {
            if (s[i][j] == '#' && s[i+1][j] != '#')
                l2[i][j] = l2[i+1][j] + 1;
            else
                l2[i][j] = l2[i+1][j];
            if (s[i][j] == '#' && s[i][j+1] != '#')
                h2[i][j] = h2[i][j+1] + 1;
            else
                h2[i][j] = h2[i][j+1];
        }
    }
    for (int i = 1;i <= n;i++) {
        bool fl = false;
        for (int j = 1;j <= m;j++) {
            if (l1[i][j] == l1[n][j] && l2[1][j] == l2[i][j] && h1[i][m] == h1[i][j] && h2[i][1] == h2[i][j]) {
                fl = true;
                break;
            }
        }
        if (!fl) {
            cout << -1 << endl;
            return 0;
        }
    }
    for (int j = 1;j <= m;j++) {
        bool fl = false;
        for (int i = 1;i <= n;i++) {
            if (l1[i][j] == l1[n][j] && l2[1][j] == l2[i][j] && h1[i][m] == h1[i][j] && h2[i][1] == h2[i][j]) {
                fl = true;
                break;
            }
        }
        if (!fl) {
            cout << -1 << endl;
            return 0;
        }
    }
    cout << cnt << endl;

    return 0;
}

 

posted @ 2020-07-02 22:55  _Ackerman  阅读(276)  评论(0编辑  收藏  举报