Codeforces Round #639 (Div. 2) D Monopole Magnets

整理的算法模板:ACM算法模板總結(分類詳細版)

 

D. Monopole Magnets

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

A monopole magnet is a magnet that only has one pole, either north or south. They don't actually exist since real magnets have two poles, but this is a programming contest problem, so we don't care.

There is an n×mn×m grid. Initially, you may place some north magnets and some south magnets into the cells. You are allowed to place as many magnets as you like, even multiple in the same cell.

An operation is performed as follows. Choose a north magnet and a south magnet to activate. If they are in the same row or the same column and they occupy different cells, then the north magnet moves one unit closer to the south magnet. Otherwise, if they occupy the same cell or do not share a row or column, then nothing changes. Note that the south magnets are immovable.

Each cell of the grid is colored black or white. Let's consider ways to place magnets in the cells so that the following conditions are met.

  1. There is at least one south magnet in every row and every column.
  2. If a cell is colored black, then it is possible for a north magnet to occupy this cell after some sequence of operations from the initial placement.
  3. If a cell is colored white, then it is impossible for a north magnet to occupy this cell after some sequence of operations from the initial placement.

Determine if it is possible to place magnets such that these conditions are met. If it is possible, find the minimum number of north magnets required (there are no requirements on the number of south magnets).

Input

The first line contains two integers nn and mm (1≤n,m≤10001≤n,m≤1000)  — the number of rows and the number of columns, respectively.

The next nn lines describe the coloring. The ii-th of these lines contains a string of length mm, where the jj-th character denotes the color of the cell in row ii and column jj. The characters "#" and "." represent black and white, respectively. It is guaranteed, that the string will not contain any other characters.

Output

Output a single integer, the minimum possible number of north magnets required.

If there is no placement of magnets that satisfies all conditions, print a single integer −1−1.

Examples

input

Copy

3 3
.#.
###
##.

output

Copy

1

input

Copy

4 2
##
.#
.#
##

output

Copy

-1

input

Copy

4 5
....#
####.
.###.
.#...

output

Copy

2

input

Copy

2 1
.
#

output

Copy

-1

input

Copy

3 5
.....
.....
.....

output

Copy

0

Note

In the first test, here is an example placement of magnets:

In the second test, we can show that no required placement of magnets exists. Here are three example placements that fail to meet the requirements. The first example violates rule 33 since we can move the north magnet down onto a white square. The second example violates rule 22 since we cannot move the north magnet to the bottom-left black square by any sequence of operations. The third example violates rule 11 since there is no south magnet in the first column.

In the third test, here is an example placement of magnets. We can show that there is no required placement of magnets with fewer north magnets.

In the fourth test, we can show that no required placement of magnets exists. Here are two example placements that fail to meet the requirements. The first example violates rule 11 since there is no south magnet in the first row. The second example violates rules 11 and 33 since there is no south magnet in the second row and we can move the north magnet up one unit onto a white square.

In the fifth test, we can put the south magnet in each cell and no north magnets. Because there are no black cells, it will be a correct placement.

 

 題意:

 

給你一幅圖,‘#’代表黑格,‘.’代表白格,讓你在滿足以下條件的情況下計算出最少的需要擺放的指北針數,若無解則輸出-1

1:每行每列必須至少有一枚指南針

2:指北針能到達所有的黑格

3:指北針不能到達任何一個白格 

如果指北針所在的行和列存在指南針,指北針可以向指南針的方向移動;

 思路:

首先我們考慮無解的情況,通過觀察我們可以發現如果每行或每列中的任意兩個黑格之間存在白格,那麼是無解的,

原因如下:

若兩個黑格所在的塊中都有一枚指南針,那麼當指北針在其中一塊時,肯定會被另一塊的

指南針所吸引,從而到達白格,違背了條件3

若黑格中全都擺放指北針,如果不違背條件1,那麼必須在白格擺放指南針,那麼指北針還是能到達白格,違背條件3

若在一個黑塊中全都擺放指北針,另一個黑塊中擺放指南針,同樣會違背條件3

第二種無解的情況:

有全爲白格的行(列)但無全爲白格的列(行)

這種情況下無論在空行白格處任何地方放指南針都會吸引黑色格子裏的指北針到達白格

判斷好這兩種情況後,只需要dfs求聯通塊個數即可。

(摘自:https://www.cnblogs.com/ljxdtc666/p/12845431.html講的真心好)

#include <bits/stdc++.h>
using namespace std;
char g[1005][1005];
int n,m,ans;
int dix[4]={0,0,1,-1},diy[4]={1,-1,0,0};
bool st[1005][1005];
void dfs(int x,int y)
{
    if(x<0||x>=n||y<0||y>=m||st[x][y]||g[x][y]=='.') return ;
    st[x][y]=true;
    for(int i=0;i<4;i++)
    {
        int xx=dix[i]+x,yy=diy[i]+y;
        dfs(xx,yy);
    }
}
int main()
{
    cin >>n>>m;
    for(int i=0;i<n;i++)
    {
        getchar();
        for(int j=0;j<m;j++)
        {
            scanf("%c",&g[i][j]);
        }
    }
    int flag1=0,flag2=0,flag3=0;
    for(int i=0;i<n;i++)
    {
        int pre=-1;
        int pos=1;
        for(int j=0;j<m;j++)
        {
            if(g[i][j]=='#')
            {
                if(!st[i][j]) dfs(i,j),ans++;
                
                pos=0;
                if(pre!=-1&&j-pre>1)
                {
                    flag1=1;
                    break;
                }
                pre=j;
            }
        }
        if(pos) flag2=1;
        if(flag1) break;
    }
    for(int j=0;j<m;j++)
    {
        int pre=-1;
        int pos=1;
        for(int i=0;i<n;i++)
        {
            if(g[i][j]=='#')
            {
                pos=0;
                if(pre!=-1&&i-pre>1)
                {
                    flag1=1;
                    break;
                }
                pre=i;
            }
        }
        if(pos) flag3=1;
        if(flag1) break;
    }
    if(flag1||(flag2&&!flag3)||(!flag2&&flag3)) cout <<-1<<endl;
    else cout <<ans<<endl;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章