ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

TZOJ 5113: Starry Night

2020-05-07 16:55:57  阅读:402  来源: 互联网

标签:map 5113 int Night sky up cluster clusters TZOJ


5113: Starry Night 分享至QQ空间

时间限制(普通/Java):1000MS/3000MS     内存限制:65536KByte
总提交: 3            测试通过:3

描述

High up in the night sky, the shining stars appear in clusters of various shapes. A cluster is a non-empty group of neighbouring stars, adjacent in horizontal, vertical or diagonal direction. A cluster cannot be a part of a larger cluster.

Clusters may be similar. Two clusters are similar if they have the same shape and number of stars, irrespective of their orientation. In general, the number of possible orientations for a cluster is eight, as Figure 1 exemplifies.

Figure 1. Eight similar clusters 
Figure 1. Eight similar clusters

The night sky is represented by a sky map, which is a two-dimensional matrix of 0's and 1's. A cell contains the digit 1 if it has a star, and the digit 0 otherwise.

Given a sky map, mark all the clusters with lower case letters. Similar clusters must be marked with the same letter; non-similar clusters must be marked with different letters.

You mark a cluster with a lower case letter by replacing every 1 in the cluster by that lower case letter.

输入

The first two lines contain, respectively, the width W and the height H of a sky map. The sky map is given in the following H lines, of W characters each.

Constraints

0 <= W (width of the sky map) <= 100
0 <= H (height of the sky map) <= 100
0 <= Number of clusters <= 500
0 <= Number of non-similar clusters <= 26 (a..z)
1 <= Number of stars per cluster <= 160

输出

The output file contains the same map as the input file, except that the clusters are marked as described in Task.

There will generally be more than one way to label the clusters with letters. Your program should choose the labeling such that if the entire output file is read as a string, this string will be minimal in the lexicographical ordering.

样例输入

23
15
10001000000000010000000
01111100011111000101101
01000000010001000111111
00000000010101000101111
00000111010001000000000
00001001011111000000000
10000001000000000000000
00101000000111110010000
00001000000100010011111
00000001110101010100010
00000100110100010000000
00010001110111110000000
00100001110000000100000
00001000100001000100101
00000001110001000111000

样例输出

 

a000a0000000000b0000000
0aaaaa000ccccc000d0dd0d
0a0000000c000c000dddddd
000000000c0b0c000d0dddd
00000eee0c000c000000000
0000e00e0ccccc000000000
b000000e000000000000000
00b0f000000ccccc00a0000
0000f000000c000c00aaaaa
0000000ddd0c0b0c0a000a0
00000b00dd0c000c0000000
000g000ddd0ccccc0000000
00g0000ddd0000000e00000
0000b000d0000f000e00e0b
0000000ddd000f000eee000

提示

In this case, the sky map has width 23 and height 15. Just to make it clearer, notice that this input file corresponds to the following picture of the sky.

Figure 2. Picture of thesky
Figure 2. Picture of the sky

This is one possible result for the sample input above. Notice that this output file corresponds to the following picture.


Figure 3. Picture with the clusters marked

题意:有多个连通块,如果两个连通块 通过旋转90度,对称翻转后形状相同,则两个连通块归属为相同,按照行列的顺序用字符编号

#include<bits/stdc++.h>
using namespace std;
int w,h;
int up,l;
int bottom,r;
struct point{
    int x,y;
};
char s[105][105],f[505];
bool vis[105][105];
vector<point> v[505],vk[505];
int dtx[]={-1,-1,-1,0,0,1,1,1};
int dty[]={0,1,-1,1,-1,1,0,-1};
bool check(int x,int y){
     if(x<0||x>=h||y<0||y>=w)return false;
     return true;
}
void bfs(int x,int y,int id){
     queue<point> q;
     l=w;
     up=h;
     q.push((point){x,y});
     vis[x][y]=1;
     while(!q.empty()){
         point u=q.front();
         v[id].push_back(u);
         q.pop();
         l=min(l,u.y);
         up=min(up,u.x);
         for(int i=0;i<8;i++){
            point v=u;
            v.x+=dtx[i];
            v.y+=dty[i];
            if(!check(x,y))continue;
            if(vis[v.x][v.y]==0&&s[v.x][v.y]=='1'){
                q.push(v);
                vis[v.x][v.y]=1;
            }
         }
     }
}
void get_vk(int id){
      for(int i=0;i<v[id].size();i++){
        vk[id].push_back((point){v[id][i].x-up,v[id][i].y-l});
      }
}
bool cmp(point a,point b){
     return a.x<b.x||a.x==b.x&&a.y<b.y;
}
bool check_equal(vector<point> a,vector<point> b){
     sort(a.begin(),a.end(),cmp);
     sort(b.begin(),b.end(),cmp);
     for(int i=0;i<a.size();i++){
        if(a[i].x!=b[i].x||a[i].y!=b[i].y)
            return false;
     }
     return true;
}
void set_data(vector<point> &a){//获得图形的边界
    bottom=-1,r=-1;
    for(int i=0;i<a.size();i++){
         bottom=max(a[i].x,bottom);
         r=max(a[i].y,r);
    }
}
void Reverse(vector<point> &a){ //左右翻转
    set_data(a);
    for(int i=0;i<a.size();i++){
        a[i].y=(r-a[i].y);
    }
}
void spin(vector<point> &a){//逆时针旋转
    set_data(a);
    for(int i=0;i<a.size();i++){
        int z=a[i].y;
        a[i].y=a[i].x;
        a[i].x=(r-z);
    }
}
/*/char shape[105][105];
void out_shape(vector<point> &a){
    set_data(a);
    for(int i=0;i<=bottom;i++)
        for(int j=0;j<=r;j++)
          shape[i][j]='0';
    for(int i=0;i<a.size();i++){
        shape[a[i].x][a[i].y]='1';
    }
    printf("%d\n",a.size());
    for(int i=0;i<=bottom;i++)
        {for(int j=0;j<=r;j++)
          printf("%c",shape[i][j]);
          printf("\n");
        }
        printf("\n");
}/*/
bool judge(int x,int y){//判断两个图形是否相似
      vector<point> vr,vt;
      vr=vk[x];vt=vk[y];
      for(int i=1;i<=4;i++){
         spin(vr);
         //out_shape(vr);
         if(check_equal(vr,vt))return true;
         Reverse(vr);
         //out_shape(vr);
         if(check_equal(vr,vt))return true;
         Reverse(vr);
         //out_shape(vr);
      }
      return false;
}
int main(){
     scanf("%d%d",&w,&h);
     for(int i=0;i<h;i++){
        scanf("%s",s[i]);
     }
     int k=0;
     for(int i=0;i<h;i++){
         for(int j=0;j<w;j++){
            if(s[i][j]=='1'&&vis[i][j]==0){
                bfs(i,j,++k);//bfs 查找连通块
                get_vk(k); //图像左移上移
            }
         }
     }
     char ch='a';
     f[1]='a';   //第一个连通块为a
     for(int i=2;i<=k;i++){
         int flag=0;
         for(int j=1;j<i;j++){//和已判断连通块进行比较
            if(vk[i].size()!=vk[j].size())continue;//点数不同直接跳过
            if(judge(i,j)){ //图像相似
                flag=1;
                f[i]=f[j];
                break;
            }
         }
         if(!flag)f[i]=++ch;//未有相似图像,新增图像字符
     }
     for(int i=1;i<=k;i++){
        for(int j=0;j<v[i].size();j++){
            s[v[i][j].x][v[i][j].y]=f[i];
        }
     } //字符设置
     for(int i=0;i<h;i++){
        printf("%s\n",s[i]);
     }
}
View Code

 

标签:map,5113,int,Night,sky,up,cluster,clusters,TZOJ
来源: https://www.cnblogs.com/llhsbg/p/12844032.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有