题解 P2749 【[USACO5.1]夜空繁星Starry Night】

· · 题解

求联通块部分同,dfs扫

然后看是不是相似用了一种很神奇的方式:求两两之间的距离,然后加起来。

然后可以AC了

/*
ID: ylx14271
PROG: starry 
LANG: C++     
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m;
int a[510][110];
char f[510][110];

int x4[510][110],y4[510][110];
double s[510];//距离和 
char c[510];
int n1,n2;

int t[510];
char ch;
double d(int x2,int y2,int x3,int y3)
{
    return sqrt((x2-x3)*(x2-x3)+(y2-y3)*(y2-y3));
}
int check(int h)//求距离
{
    for (int i1=1;i1<=n2;i1++)
        for (int j1=1;j1<=n2;j1++)
        s[h]+=d(x4[n1][i1],y4[n1][i1],x4[n1][j1],y4[n1][j1]);
    for (int ii=1;ii<n1;ii++)//是否存在相同的图形
        if (fabs(s[h]-s[ii])<=0.00001) return ii;
    return 0;
}
void dfs(int x,int y)//dfs标联通块
{
    int xx,yy;
    for (int i1=-1;i1<=1;i1++)
        for (int j1=-1;j1<=1;j1++)
        {
            if (i1==0&&j1==0) continue;
            xx=x+i1;yy=y+j1;
            if (xx<=0||yy<=0||xx>n||yy>m||a[xx][yy]==0||f[xx][yy]!='0') continue;
            f[xx][yy]=ch;.//标记
            n2++;
            x4[n1][n2]=xx;//把联通块n1的所有点都存起来算距离
            y4[n1][n2]=yy;
            dfs(xx,yy);
        }
    return;
}
int main()
{
    scanf("%d%d",&m,&n);
    for (int i=1;i<=n;i++)//读入 
        for (int j=1;j<=m;j++)
        {
            ch=getchar();
            while (ch!='0'&&ch!='1') ch=getchar();
            if (ch=='0') a[i][j]=0; else a[i][j]=1;
        }
    ch='a'-1;
    memset(f,'0',sizeof(f));
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
        if (f[i][j]=='0'&&a[i][j]==1) 
        {
            n2=1,n1++;
            x4[n1][n2]=i,y4[n1][n2]=j;//标记起来求距离 
            ch++;
            c[n1]=ch;
            f[i][j]=ch,dfs(i,j);
            int flag=0;
            flag=check(n1); 
            if (flag!=0)//存在相同的联通块
            {
                ch--;
                for (int i1=1;i1<=n2;i1++) f[x4[n1][i1]][y4[n1][i1]]=c[flag];//一个一个点的改标记
            } 
        }
    //for (int i=1;i<=n1;i++) printf("%.4f ",s[i]); 
    //cout<<endl;
    for (int i=1;i<=n;i++)//输出
    {
        for (int j=1;j<=m;j++) printf("%c",f[i][j]);
        printf("\n");
    }
    return 0;
}