IOI1998 Starry Night

来源:互联网 发布:广州知豆电动车官网 编辑:程序博客网 时间:2024/05/10 04:32

移步到新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 startalstart=arstart=blstart=brstart=0; alend=arend=blend=brend=210;FindStartEnd(amap,bmap);while (alstart<=alend){switch(mode){case 0://Normalif (alend-alstart!=blend-blstart) return false;if (L[amap][alstart]!=L[bmap][blstart]) return false;alstart++; blstart++;break;case 1://180if (alend-alstart!=blend-blstart) return false;if (L[amap][alstart]!=L[bmap][blend]) return false;alstart++; blend--;break;case 2://90 Rif (alend-alstart!=brend-brstart) return false; if (L[amap][alstart]!=R[bmap][brend]) return false;alstart++; brend--;break;case 3://90 Lif (alend-alstart!=brend-brstart) return false;if (L[amap][alstart]!=R[bmap][brstart]) return false;alstart++; brstart++;break;case 4://revif (alend-alstart!=blend-blstart) return false;if (L[amap][alstart]!=L[bmap][blstart]) return false;alstart++; blstart++;break;case 5://rev+90Lif (alend-alstart!=brend-brstart) return false;if (L[amap][alstart]!=R[bmap][brstart]) return false;alstart++; brstart++;break;case 6://rev+90Rif (alend-alstart!=brend-brstart) return false;if (L[amap][alstart]!=R[bmap][brend]) return false;alstart++; brend--;break;case 7://rev+180if (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://Normalif (arend-arstart!=brend-brstart) return false;if (R[amap][arstart]!=R[bmap][brstart]) return false;arstart++; brstart++;break;case 1://180if (arend-arstart!=brend-brstart) return false;if (R[amap][arstart]!=R[bmap][brend]) return false;arstart++; brend--;break;case 2://90 Rif (arend-arstart!=blend-blstart) return false;if (R[amap][arstart]!=L[bmap][blstart]) return false;arstart++; blstart++;break;case 3://90 Lif (arend-arstart!=blend-blstart) return false;if (R[amap][arstart]!=L[bmap][blend]) return false;arstart++; blend--;break;case 4://revif (arend-arstart!=brend-brstart) return false;if (R[amap][arstart]!=R[bmap][brend]) return false;arstart++; brend--;break;case 5://rev+90Lif (arend-arstart!=blend-blstart) return false;if (R[amap][arstart]!=L[bmap][blstart]) return false;arstart++; blstart++;break;case 6://rev+90Rif (arend-arstart!=blend-blstart) return false;if (R[amap][arstart]!=L[bmap][blend]) return false;arstart++; blend--;break;case 7://rev+180if (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;}




原创粉丝点击