hihoCoder1310 岛屿 (dfs)
思路:首先dfs求得所有联通块,再搜索的同时把每个联通块的坐标都保存下来,然后把每个联通块处理一下–首先得到某个联通块的最小横坐标和纵坐标,然后让每个坐标去减去这个横坐标和纵坐标。相当于使得所有联通块都位于左上角了,然后再对坐标按照x和y排序就可以保证相同的联通块的所有坐标都一致。
后来想了一下,其实可以不排序,因为我们都是两层循环枚举一个点来进行扩展的,如果两个联通块(岛屿)形状一致,那么每次开始搜索的起点都是同一个位置,并且搜索时保证方向一直是(上下左右或则其他),只要保证方向不变那么就不需要排序。
AC代码
#include <stdio.h>
#include <string.h>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
#define inf 0x3f3f3f3f
const int maxn = 50+5;
int n, m;
char a[maxn][maxn];
bool vis[maxn][maxn];
int numOfIsland, numOfArea, numOfShape;
map<int, int> area;
struct pos{
int x, y;
pos(int x, int y):x(x), y(y){
}
bool operator < (const pos& p) const {
return x < p.x || (x == p.x && y < p.y);
}
};
struct pic{
vector<pos> arr;
void push(pos p) {
arr.push_back(p);
}
void deal() {
int Area = arr.size();
if(!area.count(Area)) {
area[Area] = 1;
numOfArea++;
}
int x = inf, y = inf;
for(int i = 0; i < arr.size(); i++) {
x = min(x, arr[i].x);
y = min(y, arr[i].y);
}
for(int i = 0; i < arr.size(); i++) {
arr[i].x -= x;
arr[i].y -= y;
}
sort(arr.begin(), arr.end());
}
}shape[maxn*maxn];
bool isSame(pic &a, pic &b) {
vector<pos> &p1 = a.arr, &p2 = b.arr;
if(p1.size() != p2.size()) {
return false;
}
for(int i = 0; i < p1.size(); i++) {
if(p1[i].x != p2[i].x || p1[i].y != p2[i].y) return false;
}
return true;
}
void init() {
memset(vis, 0, sizeof(vis));
numOfIsland = numOfArea = numOfShape = 0;
}
const int dx[] = {0,0,-1,1};
const int dy[] = {1,-1,0,0};
void dfs(int x, int y) {
shape[numOfIsland].push(pos(x, y));
vis[x][y] = 1;
for(int i = 0; i < 4; i++) {
int px = x + dx[i];
int py = y + dy[i];
if(px < 0 || px >= n || py < 0 || py >= m) continue;
if(a[px][py] == '#' && !vis[px][py]) {
vis[px][py] = 1;
dfs(px, py);
}
}
}
int main() {
init();
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i++) {
scanf("%s", a[i]);
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(!vis[i][j] && a[i][j] == '#') {
dfs(i, j);
shape[numOfIsland].deal();
numOfIsland++;
}
}
}
for(int i = 0; i < numOfIsland; i++) {
bool ok = 1;
for(int j = 0; j < i; j++) {
if(isSame(shape[j], shape[i])) {
ok = 0;
break;
}
}
if(ok) numOfShape++;
}
printf("%d %d %d\n", numOfIsland, numOfArea, numOfShape);
return 0;
}
如有不当之处欢迎指出!
hihoCoder1310 岛屿 (dfs)的更多相关文章
- hihocoder1310 岛屿
hihocoder1310 岛屿 题意: 中文题意 思路: dfs,面积和数量都很好求,问题在岛屿形状上,感觉让人比较麻烦,用vector保存各个点,只要两个岛之间每个点距离一样就好了,这里的形状的定 ...
- hiho #1310 : 岛屿 (dfs,hash)
题目2 : 岛屿 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给你一张某一海域卫星照片,你需要统计: 1. 照片中海岛的数目 2. 照片中面积不同的海岛数目 3. 照 ...
- 305. 岛屿数量 II
题目: 假设你设计一个游戏,用一个 m 行 n 列的 2D 网格来存储你的游戏地图. 起始的时候,每个格子的地形都被默认标记为「水」.我们可以通过使用 addLand 进行操作,将位置 (row, c ...
- 每天一套题打卡|河南省第八届ACM/ICPC
A 挑战密室 化学方程式求分子量 这题我懒得写了 可以用map<string,int>哈希表,表示每种分子的相对分子质量 之后,从头遍历到尾. 1.数字:连读直到不是数字 2.字母:连读直 ...
- nyoj 1237 最大岛屿(dfs)
描述 神秘的海洋,惊险的探险之路,打捞海底宝藏,激烈的海战,海盗劫富等等.加勒比海盗,你知道吧?杰克船长驾驶着自己的的战船黑珍珠1号要征服各个海岛的海盜,最后成为海盗王. 这是一个由海洋.岛屿和海盗组 ...
- 第八届河南省赛B.最大岛屿(dfs)
B.最大岛屿 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 30 Solved: 18 [Submit][Status][Web Board] De ...
- 利用广度优先搜索(BFS)与深度优先搜索(DFS)实现岛屿个数的问题(java)
需要说明一点,要成功运行本贴代码,需要重新复制我第一篇随笔<简单的循环队列>代码(版本有更新). 进入今天的主题. 今天这篇文章主要探讨广度优先搜索(BFS)结合队列和深度优先搜索(DFS ...
- 中矿新生赛 H 璐神看岛屿【BFS/DFS求联通块/连通块区域在边界则此连通块无效】
时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32768K,其他语言65536K64bit IO Format: %lld 题目描述 璐神现在有张n*m大小的地图,地图上标明了陆地(用 ...
- nyoj--1237--最大岛屿(dfs+数据处理)
最大岛屿 时间限制:1000 ms | 内存限制:65535 KB 难度: 描述 神秘的海洋,惊险的探险之路,打捞海底宝藏,激烈的海战,海盗劫富等等.加勒比海盗,你知道吧?杰克船长驾驶着自己的的战 ...
随机推荐
- 云计算之路-阿里云上:部分服务器未及时续费造成docker swarm集群故障
非常非常抱歉,由于我们的疏忽 —— docker swarm 集群中的 2 台服务器没有及时续费,造成在夜里0点被自动关机,从而引发整个 docker swarm 集群故障,造成今天凌晨 0:30 ~ ...
- Django_MTV视图
WEB服务请求流程? 用户请求通过url,url带着用户的用户信息封装成request,然后服务器收到url请求,激活获取url中带来的request,服务器处理request逻辑后,返回封装好的re ...
- 转-Linux硬件装置和磁盘分区MBR
1 各硬件装置在Linux中的文件名 『在Linux系统中,每个装置都被当成一个文件来对待』 举例来说,SATA接口的硬盘的文件名即为/dev/sd[a-d],其中, 括号内的字母为a-d当中的任意一 ...
- lambda高级进阶--表达式参数
1,现在我们封装一个方法,来提供一个比较器,显然比较器是拥有两个参数的--用来比较的两个值. public class Linkin { public static String[] sort(Str ...
- 流API--缩减操作
在Stream流操作中,比如说min(),max(),count()方法,这几个操作都会将一个流缩减成一个值,流API将这些操作称为特例缩减.另外,流API同时泛华了缩减这种概念,提供了reduce( ...
- 获取android手机屏幕的宽高、density
public static String getDisplayMetrics(Context cx) { String str = ""; DisplayMetrics dm = ...
- Spring ioc,aop的理解
什么是控制反转? 控制反转是一种将组件依赖关系的创建和管理置于程序外部的技术. 由容器控制程序之间的关系,而不是由代码直接控制 由于控制权由代码转向了容器,所以称为反转 依赖注入,作用是避免手工在各代 ...
- Docker几个基本常识
标签(linux): docker 此文来自本人学习以及网络整理而来. 笔者Q:972581034 交流群:605799367.有任何疑问可与笔者或加群交流 对于用户来说,可能一开始在不了解的情况下会 ...
- 面向对象_04【关键字:super使用】
super关键字:解决当子类重写父类对象方法后,子类对象无法访问父类的成员1,调用父类成员变量和方法 super.成员变量 super.成员方法([参数1,参数2.......])Example: / ...
- php应用pack函数转unicode为utf8
因为时常用到json_encode去处理数据,json_encode在处理字符串遇上中文时,会把中文转换成\u5371这种格式的字符串,如果想让它能正常显示中文,则可以用pack打包函数进行处理. 以 ...