【海岛帝国模拟赛】No.1 海岛帝国:诞辰之日

 50111117海岛帝国:诞辰之日

【试题描述】

YSF自从上次“被盗投降”完(带着一大堆债)回去以后,YSF对“海盗”怀念至今,他想要建立一个“药师傅”海岛帝国。

今天,他要像“管理部”那样去探寻一个新大陆!由于YSF得到了“郭同学”TONY.STARK的赞助。买了好多好多“旧手机”。

从而以某种不法行为GET航拍地图一张!YSF开着热气球,踏(jiu)上(zuo)了(qi)征(le)程(meng)。

YSF跳伞到了一个岛上,由于YSF素有幸运儿之称,所以幸运的他降落在了最大的小岛,但是,YSF一直想了解地图中别的岛,所以请你告诉天(tong)下(xin)闻(wei)名(min)而且还在做梦的YSF,地图上一共有几个小岛,最大的(YSF自己降落的小岛)小岛有多大?(温馨提示:数字表示海拔。0表示海洋,1~9都表示陆地。此处我们把YSF的跳伞点上下左右相连接陆地均视为同一岛屿,海拔不是面积!)

输入要求

* 第一行两个整数:n,m,分别表示地图的行和列。
* 接下来的n行m列为地图。

输出要求

* 共两行,第一行为小岛的个数N,输出:有N个小岛!
* 第二行为最大的小岛的面积M,输出:YSF降落的小岛面积有M!

输入实例

 1 10 10
 2 1 2 1 0 0 0 0 0 2 3
 3 3 0 2 0 1 2 1 0 1 2
 4 4 0 1 0 1 2 3 2 0 1
 5 3 2 0 0 0 1 2 4 0 0
 6 0 0 0 0 0 0 1 5 3 0
 7 0 1 2 1 0 1 5 4 3 0
 8 0 1 2 3 1 3 6 2 1 0
 9 0 0 3 4 8 9 7 5 0 0
10 0 0 0 3 7 8 6 0 1 2
11 0 0 0 0 0 0 0 0 1 0

输出实例

有4个小岛!
YSF降落的小岛面积有38!

其它说明

地图的大小不超过50*50

试题分析

当时刚出过这样的一个乱搞而且把N个方法融合到一起的题,第一反应就是:打dfs+暴力+染色。这当然是最简单粗暴的方法。而且时间复杂度貌似不超啊~~~,所以就乱搞了这样的一个代码,每个点狂搜一遍,然后取最大值就可以求出ans2,但是,ans1怎么求呢?我们知道,目前只搜最大岛的面积函数只要两个参数,分别是x和y,表示YSF的坐标。而我们可以使用染色方法,对于每块走过的陆地染色。实现这个要求可以在我们的DFS函数里加上这样一个参数:color。原来的DFS如下:

 1 void dfs(int x,int y)
 2 {
 3     //定义一个方向数组
 4      int next[4][2]={{0,1},//向右走
 5                      {1,0},//向下走
 6                      {0,-1},//向左走
 7                      {-1,0}};//向上走
 8      int tx,ty,k;
 9      //枚举前进方向
10      for(k=0;k<=3;k++)
11      {
12          //下一步后的坐标
13          tx=x+next[k][0];
14          ty=y+next[k][1];
15          if(tx<1 || tx>n || ty<1 || ty>m) continue;//边界判断、
16          //陆地判断
17          if(a[tx][ty]>0 && book[tx][ty]==0)
18          {
19              sum++;//答案+1
20              book[tx][ty]=1;//标记为已走过
21              dfs(tx,ty);//枚举下一个点
22          }
23      }
24      return ;
25 }

改进后的DFS只加了一行,可功能大大提升了

 1 void dfs(int x,int y,int color)
 2 {
 3     //定义一个方向数组
 4      int next[4][2]={{0,1},//向右走
 5                      {1,0},//向下走
 6                      {0,-1},//向左走
 7                      {-1,0}};//向上走
 8      int tx,ty,k;
 9     a[x][y]=color;//对这个格子染色
10      //枚举前进方向
11      for(k=0;k<=3;k++)
12      {
13          //下一步后的坐标
14          tx=x+next[k][0];
15          ty=y+next[k][1];
16          if(tx<1 || tx>n || ty<1 || ty>m) continue;//边界判断、
17          //陆地判断
18          if(a[tx][ty]>0 && book[tx][ty]==0)
19          {
20              sum++;//答案+1
21              book[tx][ty]=1;//标记为已走过
22              dfs(tx,ty,color);//枚举下一个点
23          }
24      }
25      return ;
26 }

那么,既然染完色了,拿地图不就变成染色后的了吗?

想一想,有必要担心吗?

DFS1完全不会改变地图,只有DFS2会,我们先求DFS1,再求DFS2。

DFS1只会改变BOOK数组,而即使DFS1会改变地图,拿我们可以直接备份一个地图啊。

所以,可以放心的写代码了~~~

【代码】

 1 #include<iostream>
 2 using namespace std;
 3 int a[50][50];
 4 int book[50][50],n,m,sum,ans=-1,book2[50][50],sum1;
 5 void dfs(int x,int y)
 6 {
 7      int next[4][2]={{0,1},
 8                      {1,0},
 9                      {0,-1},
10                      {-1,0}};
11      int tx,ty,k;
12      for(k=0;k<=3;k++)
13      {
14          tx=x+next[k][0];
15          ty=y+next[k][1];
16          if(tx<1 || tx>n || ty<1 || ty>m) continue;
17          if(a[tx][ty]>0 && book[tx][ty]==0)
18          {
19              sum++;
20              book[tx][ty]=1;
21              dfs(tx,ty);
22          }
23      }
24      return ;
25 }
26 void dfs2(int x,int y,int color)
27 {
28      int next[4][2]={{0,1},
29                      {1,0},
30                      {0,-1},
31                      {-1,0}};
32      int tx,ty,k;
33      a[x][y]=color;
34      for(k=0;k<=3;k++)
35      {
36          tx=x+next[k][0];
37          ty=y+next[k][1];
38          if(tx<1 || tx>n || ty<1 || ty>m) continue;
39          if(a[tx][ty]>0 && book2[tx][ty]==0)
40          {
41              sum1++;
42              book2[tx][ty]=1;
43              dfs2(tx,ty,color);
44          }
45      }
46      return ;
47 }
48 int main()
49 {
50     int startx,starty,num=0;
51     cin>>n>>m;
52     for(int i=1;i<=n;i++)
53         for(int j=1;j<=m;j++)
54             cin>>a[i][j];
55     for(startx=1;startx<=n;startx++)
56         for(starty=1;starty<=m;starty++)
57         {
58             book[startx][starty]=1;
59             dfs(startx,starty);
60             book[startx][starty]=0;
61             if(sum>ans) ans=sum;
62             sum=0;
63         }
64     for(int i=1;i<=n;i++)
65         for(int j=1;j<=m;j++)
66             if(a[i][j]>0)
67             {
68                 num--;
69                 book2[i][j]=1;
70                 dfs2(i,j,num);
71             }
72     printf("有%d个小岛!\nYSF降落的小岛面积有%d!\n",-num,ans);
73 }

时间: 2024-10-16 17:44:00

【海岛帝国模拟赛】No.1 海岛帝国:诞辰之日的相关文章

【海岛帝国模拟赛】No.2 海岛帝国:“落汤鸡”市的黑帮危机

50200210海岛帝国:“落汤鸡”市的黑帮危机 [试题描述] 近几天,犯罪分子发现“药师傅”帝国的警力约等于0.(请见YSF的海岛帝国)于是开始猖狂了起来.他们选择了依山靠水(农村?)的“落汤鸡”市.开始抢劫财务,一天内发生了5起抢劫案,9起爆炸案,3起枪击案,12起绑架案!搞得YSF夜不能寐,况且每天还有那么多“怪物”要处理.于是,所有的责任都落在了“落汤鸡”市可怜的市长LTJ上.犯罪分子在LTJ市有了好多好多个窝点.市民开始惊慌起来,背井离乡.“郭同学”TONY由于YSF没还债而拒绝伸出援

首师大附中科创教育平台 我的刷题记录 0313 50111117海岛帝国:诞辰之日

今天给大家献上“C”级题:50111117海岛帝国:诞辰之日!! 试题编号:0313   50111117海岛帝国:诞辰之日 难度级别:C: 运行时间限制:1000ms: 运行空间限制:256000KB: 代码长度限制:2000000B 试题描述 YSF自从上次“被盗投降”完(带着一大堆债)回去以后,YSF对“海盗”怀念至今,他想要建立一个“药师傅”海岛帝国. 今天,他要像“管理部”那样去探寻一个新大陆!由于YSF得到了“郭同学”TONY.STARK的赞助.买了好多好多“旧手机”. 从而以某种不

【BZOJ】【2741】【FOTILE模拟赛】L

可持久化Trie+分块 神题……Orz zyf & lyd 首先我们先将整个序列搞个前缀异或和,那么某一段的异或和,就变成了两个数的异或和,所以我们就将询问[某个区间中最大的区间异或和]改变成[某个区间中 max(两个数的异或和)] 要是我们能将所有[l,r]的答案都预处理出来,那么我们就可以O(1)回答了:然而我们并不能. 一个常见的折中方案:分块! 这里先假设我们实现了一个神奇的函数ask(l,r,x),可以帮我们求出[l,r]这个区间中的数,与x最大的异或值. 我们不预处理所有的左端点,我

10.30 NFLS-NOIP模拟赛 解题报告

总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没码QAQ 现在我来写解题报告了,有点饿了QAQ.. 第一题 题目 1: 架设电话线 [Jeffrey Wang, 2007] 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务,于 是,她们要求FJ把那些老旧的电话线换成性能更好的新电话线.新的电话线架设 在已有的N(2 <=

bzoj 2741: 【FOTILE模拟赛】L 分塊+可持久化trie

2741: [FOTILE模拟赛]L Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1116  Solved: 292[Submit][Status] Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 ... xor Aj),其中l<=i<=j<=r. 为了体现在线操作,对于一个询问(x,y):

9.14 模拟赛

模拟赛第三弹~ T1 题意:给你一个数列,要求删掉任意一种整数,使得剩下的新数列中连续的相等的数最多 例如 2 7 3 7 7 3 3 7 7 5 7,删掉3以后剩的7有四个连续的,最多 思路:暴力枚举去掉哪个......这算是一道水题吧 代码丢了...... TAT T2 题意:有n本书,每本书有宽度和高度.现在你有无数个书架,每个书架的宽度为w,高度由最高的书决定 问在书本按顺序放的情况下,总的书架高度最小是多少 思路:dp,dp[i]表示做到第i本书时的最小高度和. 每次先找到能以编号j的

2014-9-9 NOIP模拟赛

东方幻想乡系列模拟赛Stage 1命题 Nettle审题 Barty ccy1991911 FlanS39 Wagner T2 高精除高精,从来没写过,不知道怎么写,我就用大数减小数ans次,果断超时. T4 Tarjan的板子题,好久没写,中间出现了一些小错误 ①是尽管有双向边,Tarjan函数中也不必排除双向边 ②Tarjan算法有时候不能一步完成,需要做最多n次,用循环解决 ③问题是关于这个题目的虽然输入n代表有n个点,但是下面的连边中有些点根本没出现过,所以设一个数组记录有效点. Pro

【题解】PAT团体程序设计天梯赛 - 模拟赛

由于本人愚笨,最后一题实在无力AC,于是只有前14题的题解Orz 总的来说,这次模拟赛的题目不算难,前14题基本上一眼就有思路,但是某些题写起来确实不太容易,编码复杂度有点高~ L1-1 N个数求和 设计一个分数类,重载加法运算符,注意要约分,用欧几里得算法求个最大公约数即可. 1 #include <cstdio> 2 3 long long abs(long long x) 4 { 5 return x < 0 ? -x : x; 6 } 7 8 long long gcd(long

20161027模拟赛解题报告

20161027模拟赛解题报告 By shenben T1 数学题 模拟即可. 注意开long long T2 技巧题 图片为本题第一张图.(无奈,图传不上来) 首先第一问图中的“Y 字形”的数量,这么简单,在此不细讲. 详见代码 O(n)累加一下就好了 主要说说第二问怎么搞 预处理 每个点分别与其他那些点相连 权值为第1,2,3大(若没有2,3大,就忽略).记录一下权值与对应的点的标号.目的是方便下面的判断. 枚举入度>=3的点,即点B(有多个) 再枚举点B相连的D点(不是点A,C). Ste