思路:首先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)的更多相关文章

  1. hihocoder1310 岛屿

    hihocoder1310 岛屿 题意: 中文题意 思路: dfs,面积和数量都很好求,问题在岛屿形状上,感觉让人比较麻烦,用vector保存各个点,只要两个岛之间每个点距离一样就好了,这里的形状的定 ...

  2. hiho #1310 : 岛屿 (dfs,hash)

    题目2 : 岛屿 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给你一张某一海域卫星照片,你需要统计: 1. 照片中海岛的数目 2. 照片中面积不同的海岛数目 3. 照 ...

  3. 305. 岛屿数量 II

    题目: 假设你设计一个游戏,用一个 m 行 n 列的 2D 网格来存储你的游戏地图. 起始的时候,每个格子的地形都被默认标记为「水」.我们可以通过使用 addLand 进行操作,将位置 (row, c ...

  4. 每天一套题打卡|河南省第八届ACM/ICPC

    A 挑战密室 化学方程式求分子量 这题我懒得写了 可以用map<string,int>哈希表,表示每种分子的相对分子质量 之后,从头遍历到尾. 1.数字:连读直到不是数字 2.字母:连读直 ...

  5. nyoj 1237 最大岛屿(dfs)

    描述 神秘的海洋,惊险的探险之路,打捞海底宝藏,激烈的海战,海盗劫富等等.加勒比海盗,你知道吧?杰克船长驾驶着自己的的战船黑珍珠1号要征服各个海岛的海盜,最后成为海盗王. 这是一个由海洋.岛屿和海盗组 ...

  6. 第八届河南省赛B.最大岛屿(dfs)

    B.最大岛屿 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 30  Solved: 18 [Submit][Status][Web Board] De ...

  7. 利用广度优先搜索(BFS)与深度优先搜索(DFS)实现岛屿个数的问题(java)

    需要说明一点,要成功运行本贴代码,需要重新复制我第一篇随笔<简单的循环队列>代码(版本有更新). 进入今天的主题. 今天这篇文章主要探讨广度优先搜索(BFS)结合队列和深度优先搜索(DFS ...

  8. 中矿新生赛 H 璐神看岛屿【BFS/DFS求联通块/连通块区域在边界则此连通块无效】

    时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32768K,其他语言65536K64bit IO Format: %lld 题目描述 璐神现在有张n*m大小的地图,地图上标明了陆地(用 ...

  9. nyoj--1237--最大岛屿(dfs+数据处理)

    最大岛屿 时间限制:1000 ms  |  内存限制:65535 KB 难度: 描述 神秘的海洋,惊险的探险之路,打捞海底宝藏,激烈的海战,海盗劫富等等.加勒比海盗,你知道吧?杰克船长驾驶着自己的的战 ...

随机推荐

  1. CSS选择器的新用法

    前面的话 现在,预处理器(如sass)似乎已经成为开发CSS的标配,正如几年前jQuery是开发JS的标配一样.JS的querySelector借鉴了jQuery的选择器思想,CSS选择器也借鉴了预处 ...

  2. [译] Linux吃掉了我的内存

    英文原文: https://www.linuxatemyram.com/ 作者: Vidar Holen 译者: thinkam 发生了什么? Linux正借用你未使用的内存来做磁盘缓存.这使你的计算 ...

  3. MySQL之SELECT用法

    主要是为了搞定一个select语句,因为语法比较奇怪,没看懂,百度了一些结果 select的东西相当于一个临时表,as就给这临时表取个名字. SELECT语句的完整语法SELECT语句的完整语法为: ...

  4. records.config文件参数解释

    # Process Records Config File # # <RECORD-TYPE> <NAME> <TYPE> <VALUE (till end ...

  5. mybatis不可忽略的细节

    自我总结,欢迎拍砖! 目的:在需要返回int,long等基础类型数据的情况下,尽量在mybatis的Mapper中用基础类型的包装类. 原因:当查询的字段为空值时,mybatis会返回null,用基础 ...

  6. Azure Functions + Azure Batch实现MP3音频转码方案

    客户需求 客户的环境是一个网络音乐播放系统,根据网络情况提供给手机用户收听各种码率的MP3歌曲,在客户没购买歌曲的情况下提供一个三十秒内的试听版本.这样一个系统非常明确地一个需求就是会定期需要将一批从 ...

  7. Jmeter Smock Test规范设计

    Jmeter Smock Test规范设计 一.Smock Test物料 1.开发运行工具Jmeter,(下载地址: http://jmeter.apache.org/download_jmeter. ...

  8. Jmeter_打印当前时间戳&打印偏移时间戳

    Jmeter中提供了一种函数,可以打印时间戳,如下图 年: yyyy 月:MM 日:dd 时: HH 分: mm 秒:ss 关于时间戳的格式,可以自由组合定义,这里我写成这样 yyyy-MM-dd H ...

  9. IntelliJ IDEA使用心得之插件篇

    今天和大家分享下插件的安装方法,顺便推荐几个非常好用的插件. 1.安装插件 在工具栏中,点击进入IDE设置界面. 插件仓库界面: 值得注意的是,每次安装/卸载插件后,需要重启IDE. 2.好用的插件 ...

  10. 在ASP.NET MVC中使用Web API和EntityFramework构建应用程序

    最近做了一个项目技术预研:在ASP.NET MVC框架中使用Web API和EntityFramework,构建一个基础的架构,并在此基础上实现基本的CRUD应用. 以下是详细的步骤. 第一步 在数据 ...