思路:首先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. k8s 如何 Failover?- 每天5分钟玩转 Docker 容器技术(127)

    上一节我们有 3 个 nginx 副本分别运行在 k8s-node1 和 k8s-node2 上.现在模拟 k8s-node2 故障,关闭该节点. 等待一段时间,Kubernetes 会检查到 k8s ...

  2. servlet 监听器分类

    http://blog.csdn.net/cxg200888/article/details/77894842

  3. android 通过getDimension,getDimensionPixelOffset和getDimensionPixelSize获取dimens.xml文件里面的变量值

    dimens.xml里写上三个变量: <dimen name="activity_vertical_margin1">16dp</dimen> <di ...

  4. Java基础知识(一)

    类与对象 1.对象:客观存在的一切事物称之为对象 类:具有相同属性和方法的对象的集合 2.类:属性,方法 3.修饰符: public protected  默认(不写)  private 任何地方   ...

  5. Event Sourcing pattern

    Event Sourcing pattern Instead of storing just the current state of the data in a domain, use an app ...

  6. absort函数和exit函数

    1. exit()函数会结束并退出程序. 1. abosrt()函数会触发程序的异常,然后程序后面的语句就不会执行了.用来提示错误.会出现:  

  7. sparse_softmax_cross_entropy_with_logits

    sparse_softmax_cross_entropy_with_logits 原创文章,请勿转载!!! 定义 sparse_softmax_cross_entropy_with_logits(_s ...

  8. 使用FileReader实现前端预览所选图片

    需求描述 在浏览器环境下进开发网站(也就是B/S架构的应用),获取到当前设备上的图片后,希望可以在上传到服务器前简单预览一下图片内容. 具体实现 主要代码 html 部分 <input type ...

  9. 使用clipboard.js实现复制内容至剪贴板

    下载插件 clipboard.js是不依赖flash,实现复制内容至剪贴板的js插件.下载clipboard.js的压缩包,根据需要选择dist目录下的压缩或未压缩版. github地址:https: ...

  10. 基于 React + Webpack 的音乐相册项目(上)

    笔记仓库:https://github.com/nnngu/LearningNotes 上一篇文章用爬虫自动下载了一些图片,这一篇就用这些图片做一个音乐相册吧! 效果预览 点击图片,切换到背面: 演示 ...