//函数:为了确定在A X B矩形中放置边长为s的k个方形瓷砖的方法的等效类数,B<=A,//在矩形的所有对称运算下。////由Chris Gribble于2014年作为Microsoft Visual Studio Express 2013下的控制台项目开发。////上传到OEIS的程序版本使用g++编译(gcc 4.5.2)。使用命名空间标准;#包括#包括#包括#包括#包括#包括#包括#包括静态常数int MaxA=30;//A的最大值。静态常数int MaxB=30;//B的最大值。静态常数int MaxS=8000000;//树中边界矩形的最大数目。静态常量int MinA=0;//A的最小值。静态常量int MinB=0;//B的最小值。静态__int64 NumMatchIdentity[MaxA];//生成的与树中其他矩形匹配的部分平铺边界矩形的数量。静态__int64无匹配数字[MaxA];//树中部分平铺的边界矩形数。静态__int64 NumMatchReflectHoriz[MaxA];//生成的部分平铺边界矩形数,当围绕水平轴反射时,与树中的其他矩形相匹配。静态__int64 NumMatchReflectVert[MaxA];//生成的部分平铺边界矩形数,当围绕垂直轴反射时,与树中的其他矩形相匹配。静态__int64 NumMatchRotate180[MaxA];//生成的部分平铺边界矩形数,当旋转180度时,与树中的其他矩形匹配。静态int LevelFirstIndex[MaxA*MaxB];//树中每个级别的第一个边界矩形的索引。静态int LevelLastIndex[MaxA*MaxB];//树中每个级别上最后一个边界矩形的索引。静态整型RectangleIndex;//部分平铺边界矩形列表中边界矩形的索引。静态短int A;//用户指定的边界矩形边长。静态短int AB;//答:B。静态短整数B;//用户指定的边界矩形边长。静态短整数电平;//树中的当前级别=放置在边界矩形中的方形平铺数。静态短int MaxNumTiles;//要放置在边界矩形中以限制计算的最大瓷砖数。静态短int MinTileSideSize;//最小瓷砖边长以减少过度计算。静态短int NumTreesBuild;//建造的树的数量。静态短整型矩形[MaxA][MaxB];//边界矩形。静态短整型***ListOfRectangles;//删除对称的所有部分平铺边界矩形的列表。fstream操作文件;//输出文件。bool matchTransformations(){//指示边界矩形的变换是否预先存在。整数n;//循环计数器。短int k,l;//循环计数器。短int match_identity;//新边界矩形和以前在同一级别生成的边界矩形之间的单元格值匹配计数。短int匹配_反射_水平;//关于横轴反射的新边界矩形与先前在同一级别生成的边界矩形之间的单元格值匹配计数。短int match_reflect_vert;//围绕纵轴反射的新边界矩形与先前在同一级别生成的边界矩形之间的单元格值匹配计数。short int match_rotate_180;//旋转180度的新边界矩形与先前在同一级别生成的边界矩形之间的单元格值匹配计数。bool transformExists=false;//指示新边界矩形的变换是否已存在于同一级别。//请检查此矩形的转换是否在同一级别上不存在。for(n=LevelFirstIndex[级别];n<RectangleIndex;n++){match_identity=0;match_reflect_horiz=0;match_reflect_vert=0;match_rotate_180=0;对于(l=0;l<B;l++){对于(k=0;k<A;k++){//身份转换。if(矩形[k][l]==矩形列表[n][k][1]){match_identity++;}//水平反射。if(矩形[A-k-1][l]==矩形列表[n][k][l]){match_reflect_horiz++;}//垂直反射。if(矩形[k][B-l-1]==矩形列表[n][k][1]){match_reflect_vert++;}//向左旋转180度。if(矩形[A-k-1][B-l-1]==矩形列表[n][k][l]){match_rotate_180++;}}}if(match_identity==AB){NumMatchIdentity[NumTreesBuild]++;transformExists=true;//操作文件<<“NumMatchIdentity=”<<NumMatch Identity[NumTreesBuild]<<endl;断裂;}else if(match_reflect_horiz==AB){NumMatchReflectHoriz[NumTreesBuilt]++;transformExists=true;//操作文件<<“NumMatchReflectHoriz=”;断裂;}else if(match_reflect_vert==AB){NumMatchReflectVert[NumTreesBuild]++;transformExists=true;//OpFile<<“NumMatchReflectVert=”<<NumMatchReflectVert[NumTreesBuilt]<<endl<<endl;断裂;}else if(match_rotate_180==AB){NumMatchRotate180[NumTreesBuild]++;transformExists=true;//操作文件<<“NumMatchRotate180=”<<NumMatch Rotate180[NumTreesBuild]<<endl;断裂;}}if(transformExists==false){NumMatchless[NumTreesBuilt]++;//操作文件<<“NumMatchless=”<<NumMatchless[NumTreesBuild]<<endl<<endl;}返回变压器存在;}void buildTree(){整数m;//循环计数器。short int空;短int标志Rectangle[MaxA][MaxB];//记录在尝试放置方形平铺的左上角而不是第一个时使用的单元格。短整数i,j,k,l;//循环计数器。short int numPartsFitted=0;short int numTiles;短int s,t;短int tileSize;短int x,y;bool emptyCell;//指示是否在边界矩形中找到空单元格。bool firstTile;//指示是否放置了特定级别的第一个平铺。布尔变换存在;//指示新边界矩形的变换是否已存在于同一级别。for(tileSize=MinTileSideSize;tileSize<=B;tileSize++){//增加生成的树的数量。NumTreesBuilded++;//OpFile<<endl<<“构建的树数=”<<NumTreesBuilt<<endl;OpFile<<endl<<“平铺边长=”<<NumTreesBuilt+MinTileSideSize-1<<endl;//构造树。//初始化。对于(i=0;i<=AB;i++){第一级指数[i]=0;LevelLastIndex[i]=0;}//在0级形成边界矩形。级别=0;矩形索引=0;LevelFirstIndex[Level]=矩形索引;LevelLastIndex[Level]=矩形索引;对于(j=0;j<B;j++){对于(i=0;i<A;i++){矩形列表[RectangleIndex][i][j]=0;}}//在标高1处形成边界矩形。//将最大方形平铺的左上角放置在边界矩形左上角四分之一内的每个位置。s=(A-瓷砖尺寸)/2+1;t=(B-瓷砖尺寸)/2+1;++级;对于(y=0;y<t;y++){对于(x=0;x<s;x++){//初始化矩形。对于(j=0;j<B;j++){对于(i=0;i<A;i++){矩形[i][j]=ListOfRectangles[LevelFirstIndex[级别-1]][i][j];}}对于(j=y;j<y+tileSize;j++){对于(i=x;i<x+tileSize;i++){矩形[i][j]=平铺大小;}}/*对于(j=0;j<B;j++){对于(i=0;i<A;i++){OpFile<<“”<<矩形[i][j];}操作文件<<endl;}操作文件<<endl;*///记录方块。矩形索引++;如果((x==0)&&(y==0){LevelFirstIndex[Level]=矩形索引;}对于(j=0;j<B;j++){对于(i=0;i<A;i++){矩形列表[RectangleIndex][i][j]=矩形[i][j];}}LevelLastIndex[Level]=矩形索引;}}//在其他级别形成矩形。numTiles=(A/tileSize)*(B/tileSize);if(numTiles>MaxNumTiles)numTiles=MaxNumPiles;对于(i=2;i<=numTiles;i++){++级;firstTile=false;对于(m=级别第一索引[级别-1];m<=级别最后索引[级别-1];m++){//记录哪些单元格不能用于放置新零件。对于(l=0;l<B;l++){对于(k=0;k<A;k++){flagRectangle[k][l]=矩形列表[m][k][1];}}//在矩形中查找下一个空单元格。查找下一个空单元格:emptyCell=假;对于(l=0;l<B;l++){对于(k=0;k<A;k++){if(flagRectangle[k][l]==0){emptyCell=真;x=l;y=k;断裂;}}如果(emptyCell==true)中断;}if(空单元格==真){//尝试将零件装配成矩形,使空单元格对应于零件的左上角。if((y+tileSize<=A)&&(x+平铺尺寸<=B)){空=0;对于(l=x;l<x+tileSize;l++){对于(k=y;k<y+tileSize;k++){if(标志矩形[k][l]==0){空++;}}}if(空==平铺大小*平铺大小){//部分适合,所以适合它。矩形索引++;if(firstTile==false){LevelFirstIndex[Level]=矩形索引;firstTile=true;}对于(l=0;l<B;l++){对于(k=0;k<A;k++){矩形[k][l]=矩形列表[m][k][1];}}for(l=x;l<x+波浪大小;l++){对于(k=y;k<y+tileSize;k++){矩形[k][l]=平铺大小;}}/*对于(l=0;l<B;l++){对于(k=0;k<A;k++){操作文件<<“”<<矩形[k][l];}操作文件<<endl;}操作文件<<endl;*///检查此矩形的转换在此级别上是否不存在。transformExists=matchTransformations();if(transformExists==true){标志矩形[y][x]=-4;//设置标志以指示此单元格的拟合成功,但不要将边界矩形放入列表中。矩形索引--;转到查找下一个空单元格;}对于(l=0;l<B;l++){对于(k=0;k<A;k++){矩形列表[RectangleIndex][k][l]=矩形[k][1];}}标志矩形[y][x]=-2;//此单元格的标志匹配成功。LevelLastIndex[Level]=矩形索引;cout<<NumTreesBuild<<“”<<Level<<“;/*对于(l=0;l<B;l++){对于(k=0;k<A;k++){操作文件<<“”<<矩形[k][l];}操作文件<<“”;对于(k=0;k<A;k++){OpFile<<“”<<flagRectangle[k][l];}操作文件<<endl;}操作文件<<endl;*///找到下一个可以放置方形瓷砖的位置。转到查找下一个空单元格;}其他的{//部分不适合,因此如果有下一个空单元格,请找到它。flagRectangle[y][x]=-1;//设置标志以指示此单元格的拟合不成功。转到查找下一个空单元格;}}其他的{//部分不适合,因此如果有下一个空单元格,请找到它。标志矩形[y][x]=-1;//设置标志以指示此单元格的拟合不成功。转到查找下一个空单元格;}}//如果结束。}//m循环结束。if(LevelLastIndex[Level]==0){//当前级别无法安装任何零件。断裂;}}//i循环结束。//输出电平数据。对于(l=0;l<=液位;l++){操作文件<<l<<“”<<LevelLastIndex[l]-LevelFirstIndex[l]+1<<endl;}}//结束(tileSize=1;tileSize<=N;tileSize++)回报;}整型main(){整数i,j;//循环计数器。//创建输出文件。OpFile.open(“SquarePlacementsInRectangle.txt”,ios_base::out|ios_base::trunc);//获取矩形的尺寸。cout<<“输入A”;cin>>A;如果((A<MinA)||(A>最大A){OpFile<<“A值”<<A<<“超出范围”<<endl;返回1;}操作文件<<“A=”<<A<<endl;cout<<“输入B”;cin>>B;如果(B<最小B)||(B>最大B)||(B>A){OpFile<<“B值”<<B<<“超出范围”<<endl;返回1;}操作文件<<“B=”<<B<<endl;AB=A*B;cout<<“输入最小瓷砖边长”;cin>>最小瓷砖边长;if((MinTileSideSize<1)||(最小平铺SideSize>B)){OpFile<<“MinTileSideSize的值”<<MinTileSideSize<<“超出范围”。<<endl;返回1;}cout<<“输入要放置的最大瓷砖数”;cin>>MaxNumTiles;if(MaxNumTiles<1){OpFile<<“MaxNumTiles的值”<<MaxNumTiles<<“超出范围”<<endl;返回1;}else if(MaxNumTiles>(A/MinTileSideSize)*(B/MinTileSideSize”){MaxNumTiles=(A/MinTileSideSize)*(B/MinTileSideSize”);}//为buildTree中使用的方块列表分配内存。ListOfRectangles=(短int***)malloc(MaxS*sizeof(短int**));对于(i=0;i<MaxS;i++){ListOfRectangles[i]=(短int**)malloc(A*sizeof(短int*));}对于(j=0;j<A;j++){对于(i=0;i<MaxS;i++){ListOfRectangles[i][j]=(短int*)malloc(B*sizeof(短int));}}buildTree();//释放内存。对于(j=0;j<A;j++){对于(i=0;i<MaxS;i++){自由(矩形列表[i][j]);}}对于(i=0;i<最大S;i++){free(矩形列表[i]);}free(矩形列表);//输出统计信息。操作文件<<endl;OpFile<<“瓷砖边长=”;对于(i=1;i<=NumTreesBuild;i++){操作文件<<i+MinTileSideSize-1<<“”;}操作文件<<endl<<endl;操作文件<<“NumMatchIdentity=”;对于(i=1;i<=NumTreesBuild;i++){操作文件<<NumMatchIdentity[i]<<“”;}操作文件<<endl;操作文件<<“NumMatchReflectHoriz=”;对于(i=1;i<=NumTreesBuild;i++){操作文件<<NumMatchReflectHoriz[i]<<“”;}操作文件<<endl;操作文件<<“NumMatchReflectVert=”;for(i=1;i<=NumTreesBuilt;i++){操作文件<<NumMatchReflectVert[i]<<“”;}操作文件<<endl;操作文件<<“NumMatchRotate180=”;对于(i=1;i<=NumTreesBuild;i++){操作文件<<NumMatchRotate180[i]<<“”;}操作文件<<endl;操作文件<<“NumMatchless=”;对于(i=1;i<=NumTreesBuild;i++){OpFile<<NumMatchless[i]<<“”;}操作文件<<endl<<endl;OpFile<<“程序完成”<<endl;返回0;}