洛谷P2749 [USACO5.1]夜空繁星Starry Night - 特殊判重 - 搜索

如何确认两个子图即使旋转了仍然是相同的???
有某个结论:当一张子图内点亮亮之间距离和相同时,这两张图“相似”
注意是许多距离的,必须要开根,不开根不是距离。不开根只能应用于两个路径的判断,他不是单判断两个距离之间是否相等,而是判断许多距离相加和许多距离相加之后的和是否相等,平方和和的平方不是一个东西
还有好多小技巧 比如说我染色的时候不必再走一遍dfs,我可以直接遍历我刚刚记下的点的位置数组(这个数组用来求两两距离和)

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath> 
using namespace std;
#define debug(x) cerr << #x << "=" << x << endl;
const int MAXN = 100 + 10;
const double eps = 1e-5;
int ori[MAXN][MAXN],vis[MAXN][MAXN],tot,tunum,coll,n,m,fan[MAXN][MAXN];
string temp;
struct tuu{
    int col;
    double sum;
}tu[MAXN*MAXN];
struct nodee{
    int x, y;
}node[MAXN*MAXN];
int dx[8] = {0,0,1,-1,1,1,-1,-1};
int dy[8] = {1,-1,0,0,1,-1,1,-1}; 
void dfs(int x, int y) {
    node[++tot].x = x, node[tot].y = y;
    fan[x][y] = 1;
    for(int i=0; i<8; i++) {
        for(int j=0; j<8; j++) {
            int nx = x + dx[i], ny = y + dy[j];
            if(ori[nx][ny] && nx >= 1 && nx <= n && ny >= 1 && ny <= m && !fan[nx][ny]) {
                dfs(nx, ny);
            }
        }
    }
}
double calc(int x1, int y1, int x2, int y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
} 
int main() {
    cin >> m >> n;
    for(int i=1; i<=n; i++) {
        cin >> temp;
        for(int j=0; j<m; j++) {
            if(temp[j] == '1') {
                ori[i][j+1] = 1; 
            }
        }
    }
    for(int i=1; i<=n; i++) {
        for(int j=1; j<=m; j++) {
            if(ori[i][j] && !vis[i][j]) {
                tot = 0;
                double sum = 0;
                dfs(i, j);
                for(int i=1; i<=tot; i++) {
                    for(int j=1; j<=tot; j++) {
                        sum += calc(node[i].x, node[i].y, node[j].x, node[j].y);
                    }
                }
                bool flg = false;
                int col = 0;
                for(int i=1; i<=tunum; i++) {
                    if(fabs(tu[i].sum - sum) <= eps) {
                        flg = true;
                        col = tu[i].col;
                        break;
                    }
                }
                if(!flg) {
                    coll++;
                    tu[++tunum].sum = sum;
                    tu[tunum].col = coll;
                    col = coll;
                }
                for(int i=1; i<=tot; i++) {
                    for(int j=1; j<=tot; j++) {
                        vis[node[i].x][node[i].y] = col;
                    }
                }
            }
        }
    }
    for(int i=1; i<=n; i++) {
        for(int j=1; j<=m; j++) {
            if(!vis[i][j]) printf("0");
            else printf("%c",vis[i][j] - 1 + 'a');
        }
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Fantasy_World/article/details/81746843