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 }

 

 

转载于:https://www.cnblogs.com/thunder-110/p/9336533.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
怎么精简代码func BasinTree(id string) ([]*models.Basin, error) { var basins []*models.Basin res := common.DB.Where("watershed_id = ?", id).Find(&basins) for _, item := range basins { if res.RowsAffected > 0 { //查询流域内所有河道 var subrivers []*models.SubRiver var rivers models.PsRiver common.DB.Model(&rivers).Where("watershed_id = ?", item.ID).Find(&subrivers) item.SubRivers = subrivers var totalL float64 common.DB.Table("ps_rivers").Select("COALESCE(sum(segment_length), 0)").Where("watershed_id = ?", item.ID).Scan(&totalL) item.TotalLength = totalL //查询流域内所有湖泊 var sublakes []*models.SubLake var lakes models.PsLake common.DB.Model(&lakes).Where("watershed_id = ?", item.ID).Find(&sublakes) var totalA float64 common.DB.Table("ps_lakes").Select("COALESCE(sum(area),0)").Where("watershed_id = ?", item.ID).Scan(&totalA) item.TotalArea = totalA item.SubLakes = sublakes } } for _, item := range basins { if res.RowsAffected > 0 { id = strconv.FormatUint(uint64(item.ID), 10) item.SubBasins, _ = BasinTree(id) for _, v := range item.SubBasins { item.TotalArea = item.TotalArea + v.TotalArea item.TotalLength = item.TotalLength + v.TotalLength } if len(item.SubBasins) == 0 { return nil, nil } } } return basins, nil } func BasinInfo(ctx *gin.Context) { id := ctx.Query("id") var req models.Basin var err error resp := models.Response{ Code: 0, Msg: "success", } if len(id) == 0 { resp.Code = 400 resp.Msg = "请输入id值" ctx.JSON(400, resp) return } res := common.DB.Where("id = ?", id).Take(&req) if res.Error != nil { resp.Code = 400 resp.Msg = "查询失败" resp.Data = res.Error ctx.JSON(400, resp) return } //查询流域内所有河道 var subrivers []*models.SubRiver var rivers models.PsRiver var totalL float64 common.DB.Model(&rivers).Where("watershed_id = ?", id).Find(&subrivers) common.DB.Table("ps_rivers").Select("COALESCE(sum(segment_length), 0)").Where("watershed_id = ?", id).Scan(&totalL) req.SubRivers = subrivers req.TotalLength = totalL //查询流域内所有湖泊 var sublakes []*models.SubLake var lakes models.PsLake var totalA float64 common.DB.Model(&lakes).Where("watershed_id = ?", id).Find(&sublakes) common.DB.Table("ps_lakes").Select("COALESCE(sum(area),0)").Where("watershed_id = ?", id).Scan(&totalA) req.SubLakes = sublakes req.TotalArea = totalA req.SubBasins, err = BasinTree(id) if err != nil { resp.Code = 500 resp.Msg = "创建树失败" resp.Data = err ctx.JSON(500, resp) return } for _, v := range req.SubBasins { req.TotalArea = req.TotalArea + v.TotalArea req.TotalLength = req.TotalLength + v.TotalLength } resp.Data = req ctx.JSON(200, resp) }
05-24

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值