列表

详情


NC236756. 画圈游戏

描述

Playf在玩画圈游戏。Playf有一张大小为  的方格图,其中有一些方格被涂上了星星的图案。Playf可以在方格内画圈,每个圈只能覆盖相邻的两个方格。Playf想要让每一个有星星图案的方格都被他画的圈覆盖,他至少要画多少个圈。
定义两个方格是相邻的,当且仅当它们有一条公共的边。

输入描述

第一行输入两个整数  ,表示方格图的大小。
接下来 n 行,每行输入 m 个字符,描述了这个方格图。其中字符'*'表示被涂上星星图案的方格,字符'o'表示空白方格。

输出描述

输出一行一个整数,表示Playf最少需要画的圆圈个数。

示例1

输入:

2 4
**o*
o**o

输出:

3

示例2

输入:

7 9
ooo**oooo
**oo*ooo*
o*oo**o**
ooooooooo
*******oo
o*o*oo*oo
*******oo

输出:

17

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 3ms, 内存消耗: 428K, 提交时间: 2022-07-29 13:11:32

#include<bits/stdc++.h>

using namespace std;

int n, m;
char s[45][45];
pair<int, int> mat[45][45];
int vis[45][45];
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
bool find(int x, int y){
    for(int i = 0; i < 4; i ++){
        int xx = x + dx[i];
        int yy = y + dy[i];
        if(xx >= 1 && xx <= n && yy >= 1 && yy <= m && s[xx][yy] == '*'){
            if(vis[xx][yy]) continue;
            vis[xx][yy] = 1;
            if(!mat[xx][yy].first || find(mat[xx][yy].first, mat[xx][yy].second)){
                mat[xx][yy] = {x, y};
                return true;
            }
        }
    }
    return false;
}

int main(){
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i ++){
        scanf("%s", s[i] + 1);
    }

    int res = 0, cnt = 0;
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= m; j ++){
            if(s[i][j] == '*') cnt ++;
            if(s[i][j] == '*' && (i + j) % 2){
                memset(vis, 0, sizeof vis);
                if(find(i, j)) res ++;
            }
        }
    }
    printf("%d\n", cnt - res);
}

C++(clang++ 11.0.1) 解法, 执行用时: 95ms, 内存消耗: 35908K, 提交时间: 2023-05-02 23:24:35

#include<bits/stdc++.h>
#define x first
#define y second
#define N 2005
using namespace std;
int n,m,dis[4][2]={{1,0},{-1,0},{0,-1},{0,1}};
char c[N][N];
bool vis[N][N];
pair<int,int> match[N][N];
bool find(int x,int y){
	for(int i=0;i<4;i++){
		int x1=x+dis[i][1];
		int y1=y+dis[i][0];
		if(x1>=1&&x1<=n&&y1>=1&&y1<=m&&!vis[x1][y1]&&c[x1][y1]=='*'){
			vis[x1][y1]=1;
			int u=match[x1][y1].x,v=match[x1][y1].y;
			if(!u||find(u,v)){
				match[x1][y1].x=x,match[x1][y1].y=y;
				return 1;
			}
		}
	}
	return 0;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>c[i]+1;
	int ans1=0,ans2=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			memset(vis,0,sizeof vis);
			if(c[i][j]=='*'){
				ans1++;
                if((i+j)&1) continue;
				if(find(i,j)) ans2++;
			}
		}
    }
	cout<<ans1-ans2<<endl;
}

上一题