码迷,mamicode.com
首页 > 其他好文 > 详细

夜空繁星(BFS,哈希)

时间:2021-01-29 12:05:43      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:sqrt   ||   并且   mic   scan   %s   point   while   span   

题意

技术图片

数据范围

\(0 \leq W,H \leq 100\),
\(0 \leq 星群数量 \leq 500\),
\(0 \leq 不相似星群数量 \leq 26\),
\(1 \leq 星群中星星的数量 \leq 160\)

思路

这个的关键主要是找到判定两个星群相似的方法。
下面有一个定理:若一个星群中所有点两两距离的和,与另一个星群相等,那么这两个星群相似。
这里给出一个直观的证明:将星群视为一个多边形,这些距离将多边形划分为一个个三角形,两个多边形划分的所有三角形全等,那个两个多边形相似。
下面证明两个多边形对应三角形全等:因为距离和相等,并且一格的长度是1,因此对应三角形的对应边都是相等的。

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>

using namespace std;

typedef pair<int, int> pii;

const int N = 110, M = N * N;
const double eps = 1e-6;

int n, m;
char g[N][N];
pii point[M];
int cnt;
bool st[N][N];
double hash_val[M];
int num;

int dx[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dy[8] = {-1, 0, 1, -1, 1, -1, 0, 1};

double get_dist(pii a, pii b)
{
    double dx = a.first - b.first;
    double dy = a.second - b.second;
    return sqrt(dx * dx + dy * dy);
}

double get_hash()
{
    double res = 0;
    for(int i = 0; i < cnt; i ++) {
        for(int j = i + 1; j < cnt; j ++) {
            res += get_dist(point[i], point[j]);
        }
    }
    return res;
}

char get_id(double hash)
{
    for(int i = 0; i < num; i ++) {
        if(fabs(hash_val[i] - hash) < eps) {
            return i + ‘a‘;
        }
    }
    hash_val[num] = hash;
    num ++;
    return num - 1 + ‘a‘;
}

void bfs(int ax, int ay)
{
    cnt = 0;
    queue<pii> que;
    que.push({ax, ay});
    st[ax][ay] = true;
    point[cnt] = {ax, ay};
    cnt ++;
    while(que.size()) {
        auto t = que.front();
        que.pop();
        int tx = t.first, ty = t.second;
        for(int i = 0; i < 8; i ++) {
            int x = tx + dx[i], y = ty + dy[i];
            if(st[x][y]) continue;
            if(x < 1 || x > n || y < 1 || y > m) continue;
            if(g[x][y] != ‘1‘) continue;
            que.push({x, y});
            st[x][y] = true;
            point[cnt] = {x, y};
            cnt ++;
        }
    }
}

int main()
{
    scanf("%d%d", &m, &n);
    for(int i = 1; i <= n; i ++) scanf("%s", g[i] + 1);
    for(int i = 1; i <= n; i ++) {
        for(int j = 1; j <= m; j ++) {
            if(g[i][j] == ‘1‘) {
                bfs(i, j);
                double hash = get_hash();
                char ch = get_id(hash);
                for(int k = 0; k < cnt; k ++) {
                    int x = point[k].first, y = point[k].second;
                    g[x][y] = ch;
                }
            }
        }
    }
    for(int i = 1; i <= n; i ++) printf("%s\n", g[i] + 1);
    return 0;
}

夜空繁星(BFS,哈希)

标签:sqrt   ||   并且   mic   scan   %s   point   while   span   

原文地址:https://www.cnblogs.com/miraclepbc/p/14341836.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!