记录编号 81472 评测结果 AAAAA
题目名称 夜空繁星 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 0.151 s
提交时间 2013-11-13 21:02:32 内存使用 0.29 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<vector>
#include<cstring>
using namespace std;
const int SIZEW=101;
const int SIZEN=501;
const int INF=0x7fffffff;
bool board[SIZEW][SIZEW]={0};
bool flag[SIZEW][SIZEW]={0};
int dx[]={0,0,0,-1,-1,-1,1,1,1};
int dy[]={0,1,-1,-1,0,1,-1,0,1};
int W,H;//H是行数,W是列数
void print(char s[SIZEW][SIZEW]){
	int i,j;
	for(i=1;i<=H;i++){
		for(j=1;j<=W;j++) printf("%c",s[i][j]);
		printf("\n");
	}
}
class POINT{//在本题中,x代表行坐标,y代表列坐标,与数学相反
public:
	int x,y;
};
bool operator != (POINT a,POINT b){
	return a.x!=b.x||a.y!=b.y;
}
bool operator < (POINT a,POINT b){//x为第一关键字,y为第二关键字
	if(a.x<b.x) return true;
	if(a.x>b.x) return false;
	return a.y<b.y;
}
class GALAXY{//不要吐槽翻译
public:
	int w,h;//w是宽度,h是高度
	int minx,miny,maxx,maxy;//刚好包裹整个星座的矩形,并非坐标最小/大的星体
	set<POINT> stars;//包含星体数为stars.size(),这里储存的是减去minx,miny之后的"偏移坐标"
	char mark;
	GALAXY(){
		minx=miny=INF;
		maxx=maxy=0;
		mark=0;
		stars.clear();
	}
	void floodfill(int,int);
	void getmember(int,int);
	void markboard(char[SIZEW][SIZEW]);
	void output(void){
		char tp[SIZEW][SIZEW]={0};
		bool flag=false;
		if(minx==INF){
			flag=true;
			minx=miny=1;
			maxx=h,maxy=w;
		}
		markboard(tp);
		int i,j;
		cout<<"galaxy:"<<endl;
		cout<<w<<" "<<h<<" "<<mark<<endl;
		for(i=minx;i<=maxx;i++){
			for(j=miny;j<=maxy;j++){
				cout<<(tp[i][j]?tp[i][j]:' ');
			}
			cout<<endl;
		}
		cout<<endl<<endl<<endl;
		if(flag) minx=miny=INF,maxx=maxy=0;
	}
	void outset(void){
		set<POINT>::iterator key;
		for(key=stars.begin();key!=stars.end();key++) cout<<(key->x)<<" "<<(key->y)<<endl;
		cout<<endl;
	}
};
bool operator == (GALAXY a,GALAXY b){//经平移后可以重叠
	if(a.w!=b.w) return false;
	if(a.h!=b.h) return false;
	if(a.stars.size()!=b.stars.size()) return false;
	set<POINT>::iterator key1,key2;
	for(key1=a.stars.begin(),key2=b.stars.begin();key1!=a.stars.end();key1++,key2++) if((*key1)!=(*key2)) return false;
	return true;
}
void GALAXY::markboard(char bd[SIZEW][SIZEW]){
	set<POINT>::iterator key;
	for(key=stars.begin();key!=stars.end();key++){
		bd[minx+key->x][miny+key->y]=mark;
	}
}
void GALAXY::floodfill(int nowx,int nowy){
	if(flag[nowx][nowy]) return;
	flag[nowx][nowy]=true;
	minx=min(minx,nowx),miny=min(miny,nowy);
	maxx=max(maxx,nowx),maxy=max(maxy,nowy);
	stars.insert((POINT){nowx,nowy});
	int nextx,nexty;
	int i;
	for(i=1;i<=8;i++){
		nextx=nowx+dx[i];
		nexty=nowy+dy[i];
		if(1<=nextx&&nextx<=H&&1<=nexty&&nexty<=W&&board[nextx][nexty]) floodfill(nextx,nexty);
	}
}
void GALAXY::getmember(int nowx,int nowy){
	floodfill(nowx,nowy);
	w=maxy-miny+1,h=maxx-minx+1;
	set<POINT>::iterator key;
	POINT temp;
	vector<POINT> tp;
	int i;
	for(key=stars.begin();key!=stars.end();key++) tp.push_back((POINT){(key->x)-minx,(key->y)-miny});
	stars.clear();
	for(i=0;i<tp.size();i++) stars.insert(tp[i]);
}
GALAXY turnac(GALAXY &g){//将g逆时针旋转90度,但矩形四角坐标为构造函数值
	GALAXY ans;
	ans.w=g.h;
	ans.h=g.w;
	ans.mark=g.mark;
	set<POINT>::iterator key;
	for(key=g.stars.begin();key!=g.stars.end();key++){
		ans.stars.insert((POINT){g.w-1-(key->y),(key->x)});
	}
	return ans;
}
GALAXY reversal(GALAXY &g){//将g左右翻转,但矩形四角坐标为构造函数值
	GALAXY ans;
	ans.w=g.w;
	ans.h=g.h;
	ans.mark=g.mark;
	set<POINT>::iterator key;
	for(key=g.stars.begin();key!=g.stars.end();key++) ans.stars.insert((POINT){(key->x),g.w-1-(key->y)});
	return ans;
}
GALAXY gals[SIZEN];
int n;
char ansboard[SIZEW][SIZEW]={0};
void markboard(void){
	int i,j;
	for(i=1;i<=H;i++){
		for(j=1;j<=W;j++) ansboard[i][j]='0';
	}
	for(i=1;i<=n;i++) gals[i].markboard(ansboard);
}
void get_similar(int x){//给与gals[x]相似的天体标号
	vector<GALAXY> nowg;
	GALAXY temp;
	temp=gals[x];
	nowg.push_back(temp);//原先
	temp=turnac(temp);
	nowg.push_back(temp);//转一次
	temp=turnac(temp);
	nowg.push_back(temp);//转两次
	temp=turnac(temp);
	nowg.push_back(temp);//转三次
	temp=reversal(gals[x]);//翻转
	nowg.push_back(temp);
	temp=turnac(temp);
	nowg.push_back(temp);//翻转转一次
	temp=turnac(temp);
	nowg.push_back(temp);//转两次
	temp=turnac(temp);
	nowg.push_back(temp);//转三次
	int i,j;
	for(i=x+1;i<=n;i++){
		for(j=0;j<nowg.size();j++){
			if(gals[i]==nowg[j]){
				gals[i].mark=gals[x].mark;
				break;
			}
		}
	}
}
void mark_similar(void){
	char ch='a';
	int i;
	for(i=1;i<=n;i++){
		if(gals[i].mark==0){
			gals[i].mark=ch++;
			get_similar(i);
		}
	}
}
void getgalaxy(void){
	int i,j;
	n=0;
	for(i=1;i<=H;i++){
		for(j=1;j<=W;j++){
			if(board[i][j]&&!flag[i][j]) gals[++n].getmember(i,j);
		}
	}
}
void read(void){
	scanf("%d%d",&W,&H);
	int i,j;
	char ch;
	string str;
	for(i=1;i<=H;i++){
		cin>>str;
		for(j=1;j<=W;j++){
			ch=str[j-1];
			board[i][j]=ch-'0';
		}
	}
}
int main(){
	freopen("starry.in","r",stdin);
	freopen("starry.out","w",stdout);
	read();
	getgalaxy();
	mark_similar();
	markboard();
	print(ansboard);
	int x=2;
	gals[x].mark='a';
	reversal(gals[x]);
	return 0;
}