4*4摩天大楼问题

news/2024/11/29 8:53:33/

给出4*4的网格平面,要求在这个16个格子里面放入楼层分别是1、2、3、4层高的楼栋;

要求每行以及每列的1~4层楼必须且只能出现一次;

给出条件是从每个方向上所能看到的不被遮挡的楼栋数目;

Example: 

To understand how the puzzle works, this is an example of a row with 2 clues. Seen from the left side there are 4 buildings visible while seen from the right side only 1: 

 

There is only one way in which the skyscrapers can be placed. From left-to-right all four buildings must be visible and no building may hide behind another building: 


Example of a 4 by 4 puzzle with the solution: 
 

代码(我这个是用穷举的方法来做的,先算出4!一共24种组合,然后依次遍历,其实比较笨,应该有更聪明的方法,以后有空了想想):

typedef struct _AssNode{int Valuegroup[4];int LeftViewCnt;int RightViewCnt;
}AssNode;int GetLeftViewCnt(int *Buff, int Sz){int i, j;int Cnt = Sz;if(Sz < 2) return Sz;/*从第二个数开始遍历,如果他前面有数比他大,说明被遮挡,返回值-1*/for(i=1; i<Sz; i++){for(j=0; j<i; j++){if(Buff[j] > Buff[i]){Cnt--;break;}}}return Cnt; 
}int GetRightViewCnt(int *Buff, int Sz){int i, j;int Cnt = Sz;if(Sz < 2) return Sz;/*从倒数第二个数开始遍历,如果他后面有数比他大,说明被遮挡,返回值-1*/for(i=Sz-2; i>=0; i--){for(j=Sz-1; j>i; j--){if(Buff[j] > Buff[i]){Cnt--;break;}}}return Cnt; 
}int Get4X4Assemble(AssNode *Assemble){int i, j, k, z;int cnt = 0;for(i=1; i<=4; i++){for(j=1; j<=4; j++){if(j == i)continue;for(k=1; k<=4; k++){if(k == i || k == j)continue;for(z=1; z<=4; z++){if(z == i || z == j || z == k)continue;Assemble[cnt].Valuegroup[0] = i;Assemble[cnt].Valuegroup[1] = j;Assemble[cnt].Valuegroup[2] = k;Assemble[cnt].Valuegroup[3] = z;Assemble[cnt].LeftViewCnt = GetLeftViewCnt(Assemble[cnt].Valuegroup, 4);Assemble[cnt].RightViewCnt = GetRightViewCnt(Assemble[cnt].Valuegroup, 4);cnt++;}}}}
}/*判断数组列是否是1'2'3'4的组合*/
int IsColumeOrder(int ** buff){int i, j;int cnt = 0;for(j=0; j<4; j++){cnt = 0;for(i=1; i<=4; i++){if((*buff)[j] == i || (*(buff+1))[j] == i|| (*(buff+2))[j] == i|| (*(buff+3))[j] == i){cnt++;}}if(cnt != 4){return 0;}}return 1;
} int** SolvePuzzle (int *clues) {AssNode Assemble[24];int **out;int colbuf[4] = {0};int col; int i,j,k,z;int ii,jj;//printf("AAA\n");out = malloc(sizeof(int*) * 4);for(i=0; i<4; i++){*(out+i) = malloc(sizeof(int) * 4);}Get4X4Assemble(Assemble); /*第一行*/ for(i=0; i<24; i++){/*找到一个符合行要求的组合*/if((clues[15] == 0 || Assemble[i].LeftViewCnt == clues[15]) && (clues[4] == 0 || Assemble[i].RightViewCnt == clues[4])){memcpy(*out, Assemble[i].Valuegroup, 4*sizeof(int));//printf("AAb\n");/*第二行*/ for(j=0; j<24; j++){/*找到一个符合行要求的组合*/if((clues[14] == 0 || Assemble[j].LeftViewCnt == clues[14]) && (clues[5] == 0 || Assemble[j].RightViewCnt == clues[5])){memcpy(*(out+1), Assemble[j].Valuegroup, 4*sizeof(int));/*第三行*/for(k=0; k<24; k++){/*找到一个符合行要求的组合*/if((clues[13] == 0 || Assemble[k].LeftViewCnt == clues[13]) && (clues[6] == 0 || Assemble[k].RightViewCnt == clues[6])){memcpy(*(out+2), Assemble[k].Valuegroup, 4*sizeof(int));//printf("AAc\n");/*第四行*/for(z=0; z<24; z++){/*找到一个符合行要求的组合*/if((clues[12] == 0 || Assemble[z].LeftViewCnt == clues[12]) && (clues[7] == 0 || Assemble[z].RightViewCnt == clues[7])){memcpy(*(out + 3), Assemble[z].Valuegroup, 4*sizeof(int));/*校验列是否正确*/if(!IsColumeOrder(out)) continue;for(col=0; col<4; col++){colbuf[0] = out[0][col];colbuf[1] = out[1][col];colbuf[2] = out[2][col];colbuf[3] = out[3][col];//printf("AAd\n");if(!((clues[col] == 0 || clues[col] == GetLeftViewCnt(colbuf, 4))&& (clues[11-col] == 0 || clues[11-col] == GetRightViewCnt(colbuf, 4)))){/*校验列不正确,终止校验*//*printf("Err: i=%d, j=%d, k=%d, z=%d\n", i,j,k,z);printf("Err: Left=%d, right=%d, clues[col]=%d, clues[11-col]=%d\n", GetLeftViewCnt(colbuf, 4),GetRightViewCnt(colbuf, 4), clues[col], clues[11-col]);for(ii=0; ii<4; ii++){for(jj=0; jj<4; jj++){printf("%d ", out[ii][jj]);}printf("\n");}*/break; }}if(col == 4){/*找到答案,返回*//*printf("Get: i=%d, j=%d, k=%d, z=%d\n", i,j,k,z);for(ii=0; ii<4; ii++){for(jj=0; jj<4; jj++){printf("%d ", out[ii][jj]);}printf("\n");}*/return out;											}}} }} }} }}//printf("return 0: i=%d, j=%d, k=%d, z=%d\n", i,j,k,z);return 0;
}

 


http://www.ppmy.cn/news/932647.html

相关文章

网页游戏外挂的设计与编写:QQ摩天大楼【一】(基本技术)

网页游戏外挂的编写很简单,不需要研究其源代码,不需要懂得汇编知识,只需要分析发送到服务器和服务器发送到本地的数据包就可以写出来。 但是如果你想尽快分析数据包中的内容并得到结果,那么你可能还需要研究一下源代码。 如果游戏是Flash做的,那么你需要下载一…

摩天大楼如何靠一颗铁球防风抗震?

引言 2021 年 5 月 18 日下午&#xff0c;钢管混凝土结构世界第一高楼、深圳地标建筑华强北赛格广场大厦&#xff08;图 1&#xff09;发生明显振动&#xff0c;高层建筑的防风抗震再次引起人们关注。 图 1: 深圳赛格大厦 经初步调查&#xff0c;造成赛格大厦震颤的主要原因是风…

摩天大楼问题

前几天呢&#xff0c;一位小老弟给我分享了这道很有意思的题目&#xff0c;可是捏&#xff0c;我找遍了网络&#xff0c;也没有找到这个题的题解&#xff0c;于是乎&#xff0c;余勇当此题拓荒者也&#xff01; 来人哪&#xff0c;把题目献上来&#xff01; 题目描述 摩天大…

世界摩天大楼TOP10

信息来源&#xff1a;南方都市报 2006年6月24日 A20版 位次名称高度楼层城市1台北101大厦508米101台湾2双子塔452米88吉隆坡3西尔斯大厦442米110芝加哥4金贸大厦421米88上海5国际金融中心二期420米90香港6中信广场391米80广州7地王大厦384米69深圳8帝国大厦381米102纽约9中环广…

什么是Java中的类加载器,它有哪些特性和用途?

Java中的类加载器是负责将Java类文件加载到内存中的一部分。它们的主要作用是将Java类文件中的字节码读取到内存中&#xff0c;并将其转换为方法可以直接调用的Java类。类加载器在Java程序的生命周期中起着至关重要的作用&#xff0c;因为Java类是动态的&#xff0c;可以在程序…

上门服务小程序|上门家政小程序开发

随着现代生活节奏的加快和人们对便利性的追求&#xff0c;上门家政服务逐渐成为了许多家庭的首选。然而&#xff0c;传统的家政服务存在着信息不透明、服务质量不稳定等问题&#xff0c;给用户带来了困扰。为了解决这些问题&#xff0c;上门家政小程序应运而生。上门家政小程序…

win7资源管理器菜单栏 无法隐藏

关闭资源管理器&#xff0c;打开注册表&#xff08;winR——输入"regedit"——确定&#xff09;&#xff0c;删除出下面这个键值&#xff0c;立刻生效。 HKEY_CURRENT_USER\Software\Microsoft\InternetExplorer\Toolbar\ShellBrowser\ITBar7Layout

计算机资源管理菜单包括哪些,玩转Win7之“资源管理器窗口” -电脑资料

WINDOWS的资源管理器一直是我们使用计算机时和文件打交道的重要工具&#xff0c;在WIN7中&#xff0c;我们会发现新的资源管理器使我们可以更容易地管理和搜索自己的目标文件和目录&#xff0c; 隐藏的文件菜单 初接触WIN7的用户可能会感到奇怪&#xff1a;无论是打开资源管理器…