IOI1998 Starry Night

移步到新Blog 获得更好的代码阅读体验


BFS,超级麻烦

推荐A这道模拟方块转换

高高的星空,簇簇闪耀的群星形态万千。一个星座(cluster)是一群连通的星组成的非空连通星系,这里的连通是指水平,垂直或者对角相邻的两个星星。一个星座不能是另一个更大星座的一部分, 星座可以相似(similar)。如果两个星座有相同的形状,而且包括相同数目的星体,那么不管其方向性如何,就算相似。一般而言,星座可能的方向有八个,如图1所示。

题目描述

夜空可以表示为一份天体图(sky map),它是一个由字符0和1组成的二维矩阵,字符1表示所在的位置有一颗星;字符0表示该位置上是空的.给定一份天体图,用同一个小写英文标识(mark)相似的所有星座。相似的星座必须用相同的字母标识,不同的星座表示为不同的字母。标识一个星座,就是将其中各星体对应的字符1替换为相应的小写字母.


#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
using namespace std;

bool mapx[110][110]={false};
int xx,yx;
char cmapx[110][110]={0};
int L[510][220]={0},R[510][220]={0},alstart=0,arstart=0,blstart=0,brstart=0,alend=210,arend=210,blend=210,brend=210;
int starnum[510]={0},cmapc[510]={0};

void checkLR(int x,int sl,int el,int sr,int er)
{
	printf("L\n");
	for (int i=sl;i<=el;i++) printf("%d ",L[x][i]);
	printf("\nR\n");
	for (int i=sr;i<=er;i++) printf("%d ",R[x][i]);
	printf("\n\n");
}

void FindStartEnd(int amap,int bmap)
{
	while (L[amap][alstart]==0) alstart++;
	while (R[amap][arstart]==0) arstart++;
	while (L[amap][alend]==0) alend--;
	while (R[amap][arend]==0) arend--;
	while (L[bmap][blstart]==0) blstart++;
	while (R[bmap][brstart]==0) brstart++;
	while (L[bmap][blend]==0) blend--;
	while (R[bmap][brend]==0) brend--;
	/*printf("A map L start at : %d end at : %d\n",alstart,alend);
	printf("A map R start at : %d end at : %d\n",arstart,arend);
	printf("B map L start at : %d end at : %d\n",blstart,blend);
	printf("B map R start at : %d end at : %d\n",brstart,brend);
	checkLR(amap,alstart,alend,arstart,arend);
	checkLR(bmap,blstart,blend,brstart,brend);*/
}

bool match(int amap,int bmap,int mode)
{
	//find a start
	alstart=arstart=blstart=brstart=0; alend=arend=blend=brend=210;
	FindStartEnd(amap,bmap);
	
	while (alstart<=alend)
	{
		switch(mode)
		{
		case 0://Normal
			if (alend-alstart!=blend-blstart) return false;
			if (L[amap][alstart]!=L[bmap][blstart]) return false;
			alstart++; blstart++;
			break;
		case 1://180
			if (alend-alstart!=blend-blstart) return false;
			if (L[amap][alstart]!=L[bmap][blend]) return false;
			alstart++; blend--;
			break;
		case 2://90 R
			if (alend-alstart!=brend-brstart) return false; 
			if (L[amap][alstart]!=R[bmap][brend]) return false;
			alstart++; brend--;
			break;
		case 3://90 L
			if (alend-alstart!=brend-brstart) return false;
			if (L[amap][alstart]!=R[bmap][brstart]) return false;
			alstart++; brstart++;
			break;
		case 4://rev
			if (alend-alstart!=blend-blstart) return false;
			if (L[amap][alstart]!=L[bmap][blstart]) return false;
			alstart++; blstart++;
			break;
		case 5://rev+90L
			if (alend-alstart!=brend-brstart) return false;
			if (L[amap][alstart]!=R[bmap][brstart]) return false;
			alstart++; brstart++;
			break;
		case 6://rev+90R
			if (alend-alstart!=brend-brstart) return false;
			if (L[amap][alstart]!=R[bmap][brend]) return false;
			alstart++; brend--;
			break;
		case 7://rev+180
			if (alend-alstart!=blend-blstart) return false;
			if (L[amap][alstart]!=L[bmap][blend]) return false;
			alstart++; blend--;
			break;
		}
	}
	while (arstart<=arend)
	{
		switch(mode)
		{
		case 0://Normal
			if (arend-arstart!=brend-brstart) return false;
			if (R[amap][arstart]!=R[bmap][brstart]) return false;
			arstart++; brstart++;
			break;
		case 1://180
			if (arend-arstart!=brend-brstart) return false;
			if (R[amap][arstart]!=R[bmap][brend]) return false;
			arstart++; brend--;
			break;
		case 2://90 R
			if (arend-arstart!=blend-blstart) return false;
			if (R[amap][arstart]!=L[bmap][blstart]) return false;
			arstart++; blstart++;
			break;
		case 3://90 L
			if (arend-arstart!=blend-blstart) return false;
			if (R[amap][arstart]!=L[bmap][blend]) return false;
			arstart++; blend--;
			break;
		case 4://rev
			if (arend-arstart!=brend-brstart) return false;
			if (R[amap][arstart]!=R[bmap][brend]) return false;
			arstart++; brend--;
			break;
		case 5://rev+90L
			if (arend-arstart!=blend-blstart) return false;
			if (R[amap][arstart]!=L[bmap][blstart]) return false;
			arstart++; blstart++;
			break;
		case 6://rev+90R
			if (arend-arstart!=blend-blstart) return false;
			if (R[amap][arstart]!=L[bmap][blend]) return false;
			arstart++; blend--;
			break;
		case 7://rev+180
			if (arend-arstart!=brend-brstart) return false;
			if (R[amap][arstart]!=R[bmap][brstart]) return false;
			arstart++; brstart++;
			break;
		}
	}
	//printf("Perfect MATCHED!    at mode %d\n",mode);
	return true;
}

void Ffill()  //灌水 
{
	queue<int> quex,quey; //XY轴队列 
	int cache1,cache2,cachex,cachey,fcounter=96,mapcounter=0;  //缓存 染色计数器 子星座计数器 
	int wayx[8]={-1,-1,-1,0,1,1,1,0},wayy[8]={-1,0,1,1,1,0,-1,-1}; //方向表 
	bool matchflag=false;  //匹配标志 
	
	for (int i=0;i<=xx;i++)
		for (int j=0;j<=yx;j++) if (mapx[i][j]==true)  //瞎灌水 
		{
			matchflag=false;
			quex.push(i); quey.push(j); fcounter++; mapcounter++;
			mapx[i][j]=false; cmapc[mapcounter]=fcounter;
			
			while (quex.empty()==false)
			{
				cachex=quex.front(); cachey=quey.front();
				quex.pop(); quey.pop();
				
				cmapx[cachex][cachey]=(char) fcounter; //把他染色 
				L[mapcounter][cachex-i+105]++; R[mapcounter][cachey-j+105]++;	//建立WZK表 
				starnum[mapcounter]++;  //子星图的星星数目加1 
				
				for (int w=0;w<=7;w++) if (mapx[cachex+wayx[w]][cachey+wayy[w]]==true)  //瞎灌水x2 
				{
					quex.push(cachex+wayx[w]); quey.push(cachey+wayy[w]);
					mapx[cachex+wayx[w]][cachey+wayy[w]]=false;
				}
			}//Flood Fill ended.
			
			for (int m=1;m<mapcounter;m++) //寻找之前的子星图 
			{
				if (matchflag) break;  
				if (starnum[m]==starnum[mapcounter]) /*如果星星数目相同*/
				   for (int x=0;x<=7;x++) if (match(m,mapcounter,x)==true) //旋转8次判断 
				   {
 	     		        matchflag=true;  //成功匹配 
					   	for (int k=0;k<=xx;k++)  //替换字符 
						for (int l=0;l<=yx;l++)
							if (cmapx[k][l]==(char) fcounter) cmapx[k][l]=(char) cmapc[m]; 
						cmapc[mapcounter]=cmapc[m];
						fcounter--;
					break;
					}
			}
		}
}

int main()
{
	char inmap[110]={0};
	scanf("%d%d",&yx,&xx);
	for (int i=1;i<=xx;i++)
	{
		scanf("%s",inmap);
		for (int j=0;j<strlen(inmap);j++) if (inmap[j]=='1') mapx[i][j+1]=true; //构建一个星系图 
	}
	
	Ffill();  //灌一遍水 
	
	for (int i=1;i<=xx;i++) 
	{
		for (int j=1;j<=yx;j++)
		{
			if (cmapx[i][j]!=0) printf("%c",cmapx[i][j]);
			else printf("0");
		}
		printf("\n");
	}
	return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值