D. Lakes in Berland (DFS或者BFS +连通块

 

 

https://blog.csdn.net/guhaiteng/article/details/52730373 参考题解

 

http://codeforces.com/contest/723/problem/D  原题目

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include <cctype>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<string>
 8 #include<cmath>
 9 #include<set>
10 #include<vector>
11 #include<stack>
12 #include<queue>
13 #include<map>
14 using namespace std;
15 #define ll long long
16 #define mem(a,x) memset(a,x,sizeof(a))
17 #define se second
18 #define fi first
19 const int INF= 0x3f3f3f3f;
20 const int N=2e5+5;
21 
22 int n,m,k;
23 char mp[55][55];
24 int vis[55][55]={0},tian[2600]={0};
25 int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
26 int nn=0,cnt=0,flag=0,num=0;
27 
28 pair<int,int>v[2600];
29 
30 bool cmp(pair<int,int> c ,pair<int,int> d)
31 {
32     return c.second<d.second;
33 }
34 
35 void dfs(int nx,int ny)
36 {
37     num++; //块数++
38     vis[nx][ny]=cnt; //是属于第几个块的 就涂第几种颜色
39     if(nx==n||nx==1||ny==1||ny==m) flag=1; //如果是海,就不能记入v中
40     for(int i=0;i<4;i++)
41     {
42         int x=nx+dx[i],y=ny+dy[i];
43         if(x>n||x<1||y<1||y>m||mp[x][y]!='.'||vis[x][y]) continue;
44         dfs(x,y);
45     }
46 }
47 
48 int main()
49 {
50     cin>>n>>m>>k;
51     for(int i=1;i<=n;i++)
52         scanf("%s",mp[i]+1);
53     for(int i=1;i<=n;i++)
54     {
55         for(int j=1;j<=m;j++)
56         {
57             if(mp[i][j]=='.'&& vis[i][j]==0)
58             {
59                 num=0; //这个块 有多大
60                 flag=0;
61                 cnt++; //有几个联通块
62                 dfs(i,j);
63                 if(flag==0) {
64                     nn++;
65                     v[nn].first=cnt;
66                     v[nn].second=num;
67                 }
68             }
69         }
70     }
71     sort(v+1,v+1+nn,cmp); //升序
72     int ans=0; //需要填的所有块的总大小 即总cell数
73     int u=1;
74     int V=nn;
75     while(V>k)
76     {
77         V--;
78         ans+=v[u].second;
79         tian[ v[u].first ]=1;//填的第几块连通的区域标记为1
80         u++;
81     }
82 
83     cout<<ans<<endl;
84     for(int i=1;i<=n;i++)
85     {
86         for(int j=1;j<=m;j++)
87         {
88             if( tian[ vis[i][j] ] ) //如果填的第vis[i][j]块的区域标记为1
89                 cout<<'*'; //就填了
90             else cout<<mp[i][j];
91         }
92         cout<<endl;
93     }
94 }

 

 

BFS:

第一次先把湖找出来,并记录湖的大小,然后存在结构体node中,最后sort一下,把要填的湖再bfs一下把这个湖变成陆地。

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include <cctype>
  4 #include<algorithm>
  5 #include<cstring>
  6 #include<cmath>
  7 #include<string>
  8 #include<cmath>
  9 #include<set>
 10 #include<vector>
 11 #include<stack>
 12 #include<queue>
 13 #include<map>
 14 using namespace std;
 15 #define ll long long
 16 #define mem(a,x) memset(a,x,sizeof(a))
 17 #define se second
 18 #define fi first
 19 const int INF= 0x3f3f3f3f;
 20 const int N=2e5+5;
 21 
 22 int n,m,k;
 23 char mp[55][55];
 24 int vis[55][55]={0} ,vis2[55][55]={0};
 25 int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
 26 int nn=0,cnt=0,flag=0,num=0,ans=0;
 27 
 28 
 29 struct node
 30 {
 31     int x,y,s;
 32 }a,b,c[2600];
 33 queue<node>q;
 34 
 35 bool cmp(node u,node v)
 36 {
 37     return u.s<v.s;
 38 }
 39 
 40 void bfs(int nx,int ny)
 41 {
 42     a.x=nx;
 43     a.y=ny;
 44     vis[a.x][a.y]=1;
 45     if(a.x==1||a.y==1||a.x==n||a.y==m) flag=1; //是海不是湖
 46     q.push(a);
 47     while(!q.empty())
 48     {
 49         a=q.front(); q.pop();
 50         for(int i=0;i<4;i++)
 51         {
 52             b.x=a.x+dx[i];
 53             b.y=a.y+dy[i];
 54             if(b.x<1||b.y<1||b.x>n||b.y>m||mp[b.x][b.y]!='.'|| vis[b.x][b.y] )
 55                 continue;
 56             vis[b.x][b.y]=1;
 57 
 58             if(b.x==1||b.y==1||b.x==n||b.y==m) flag=1; //是海不是湖
 59             num++;
 60             //cout<<num<<endl;
 61 
 62             q.push(b);
 63         }
 64     }
 65 }
 66 
 67 void bfs2(int nx,int ny)
 68 {
 69     while(!q.empty()) q.pop();
 70     a.x=nx;
 71     a.y=ny;
 72     vis2[a.x][a.y]=1;
 73     mp[a.x][a.y]='*';
 74     ans++;  //总数++
 75     q.push(a);
 76     while(!q.empty())
 77     {
 78         a=q.front(); q.pop();
 79         for(int i=0;i<4;i++)
 80         {
 81             b.x=a.x+dx[i];
 82             b.y=a.y+dy[i];
 83             if(b.x<1||b.y<1||b.x>n||b.y>m||mp[b.x][b.y]!='.'|| vis2[b.x][b.y] )
 84                 continue;
 85 
 86             mp[b.x][b.y]='*';
 87             vis2[b.x][b.y]=1;
 88             ans++;
 89             q.push(b);
 90         }
 91     }
 92 }
 93 
 94 int main()
 95 {
 96     cin>>n>>m>>k;
 97     for(int i=1;i<=n;i++)
 98         scanf("%s",mp[i]+1);
 99     for(int i=1;i<=n;i++){
100         for(int j=1;j<=m;j++){
101             if(mp[i][j]=='.' && !vis[i][j])
102             {
103                 num=0;
104                 flag=0;
105                 bfs(i,j);
106                 if(!flag)
107                 {
108                     nn++;
109                     c[nn].x=i; c[nn].y=j ; c[nn].s=num;
110                     //cout<<i<<' '<<j<<endl;
111                     //cout<<num<<endl;
112                     //记录原始坐标和 这个块的格子数
113                 }
114             }
115         }
116     }
117     sort(c+1,c+1+nn,cmp); //升序
118 
119     for(int i=1;i<=nn-k ;i++) //开始填
120     {
121         bfs2(c[i].x, c[i].y); //这里开始的 一定是'.'
122     }
123 
124     cout<<ans<<endl;
125     for(int i=1;i<=n;i++)
126         printf("%s\n",mp[i]+1);
127 }

 

 
posted @ 2018-07-19 16:21  木流牛马  阅读(207)  评论(0编辑  收藏  举报