您的位置:首页 > 其它

Lakes in Berland(CF #375 Div. 2)

2017-03-03 10:29 489 查看
练习题这道题,这是一道思路很明确的题(dfs裸题+简单贪心),不过在实现细节上有些要注意的地方。

题目大意:在一个n×m的地方上有陆地和湖,那些和边缘连接的水域视为海,题目给出最后要保留k个湖,由你计算出最少要填多少陆地,并把图画出来。附链接:http://codeforces.com/problemset/problem/723/D

大体思路:计算出有num个湖,并记录下最开始找到这个湖的位置和湖的面积,保存在一个数组Node[3000]里,然后对Node数组排序,取出num-k个湖填满,计算要填的总面积,最后输出。思路很清晰。不过在判断是否是湖这一点上需要想一想怎么写。

以下是ac代码

#include<stdio.h>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

struct node{
int x,y;
int cnt;
}Node[3000];

const int maxn=60;
int n,m;
char box[maxn][maxn];
int vis[maxn][maxn];
int ans,flag;
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
int cmp(node a,node b){
return a.cnt<b.cnt;
}
void dfs(int bx,int by){ //判断有多少个湖的函数
if(bx<=0||bx>=n-1||by<=0||by>=m-1){
flag=1;
return;
}
vis[bx][by]=1;
ans++;
for(int i=0;i<4;i++){
int x=bx+dx[i];
int y=by+dy[i];
if(box[x][y]=='.'&&!vis[x][y])
bfs(x,y);
}
}
void rdfs(int bx,int by){ //填湖的函数
if(bx<0||bx>=n||by<0||by>=m)
return;
box[bx][by]='*';
for(int i=0;i<4;i++){
int x=bx+dx[i];
int y=by+dy[i];
if(box[x][y]=='.')
rbfs(x,y);
}
}
int main(){
int k;
while(scanf("%d%d%d",&n,&m,&k)!=EOF){
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)
scanf("%s",box[i]);
int num=0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
if(box[i][j]=='.'&&!vis[i][j]){
ans=0;
flag=0; //判断标志
dfs(i,j);
if(!flag)
Node[num++]={i,j,ans};
}
}
/*
for(int i=0;i<num;i++)
printf("%d %d %d\n",Node[i].x,Node[i].y,Node[i].cnt);
*/
sort(Node,Node+num,cmp);
int sum=0;
for(int i=0;i<num-k;i++){
rdfs(Node[i].x,Node[i].y); //填湖
sum+=Node[i].cnt;
}
printf("%d\n",sum);
for(int i=0;i<n;i++)
printf("%s\n",box[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dfs CF 贪心