迅雷一道上机题:nxn的方格,去掉一条对角线的两个对角...
来源:互联网 发布:本溪 农业 盘古网络 编辑:程序博客网 时间:2024/05/17 17:46
题目描述:
nxn的方格,去掉一条对角线的两个对角,余下部分用面积为2的矩形覆盖,即1x2或2x1的矩形,结果是不可能完全覆盖,请编程枚举所有的覆盖情况 。
算法描述:
这是迅雷一道机试题,在网上被反复引用。用到的方法也比较简单,就是回溯法,所以没有大神花时间去实现,网上都没有实现的代码。我用C语言实现了一版,在3×3时答案正确,4×4时有194个解。正确性有待验证,希望大家看到了实现了可以把答案和我交流下。我先抛砖引玉了。
代码:
/* *nxn的方格,去掉一条对角线的两个对角,余下部分用面积为2的矩形覆盖,即1x2或2x1的矩形,结果是不可能完全覆盖,请编程枚举所有的覆盖情况 * */#include<stdio.h>#define N 4int maze[N][N];const char dirs[] = {'^','v','<','>','O','#',0};enum enum_dir{up,down,left,right,unused,block,unvisited};int result_num = 0;int find_another(int x,int y);int set_pos_dir(int x,int y,int dir);int get_partner(int x,int y,int dir);int get_next_node(int * nx,int *ny);void print_maze();void print_result();int tell_can_unused(int x,int y);int main(){//initmaze[0][0] = dirs[block];maze[N-1][N-1] = dirs[block];//find cover casefind_another(0,1);}int find_another(int x,int y){//deal with x,yint i;for(i=up;i<=right;i++){if(1 == get_partner(x,y,i) ){int par_x,par_y,par_dir;switch(i){case up:par_x = x-1; par_y = y; par_dir = down;break;case down:par_x = x+1; par_y = y; par_dir = up;break;case left:par_x = x; par_y = y-1; par_dir = right;break;case right:par_x = x; par_y = y+1; par_dir = left;break;}set_pos_dir(x,y,i); set_pos_dir(par_x,par_y,par_dir);int next_x,next_y;if(1==get_next_node(&next_x,&next_y) ){find_another(next_x,next_y);}else{//no next node,the end print_result();}set_pos_dir(x,y,unvisited); set_pos_dir(par_x,par_y,unvisited);}}//whether the node can be an unused nodeif(0 == tell_can_unused(x,y))return 0;set_pos_dir(x,y,unused);int next_x,next_y;if(1==get_next_node(&next_x,&next_y) ){find_another(next_x,next_y);}else{//no next node,the end print_result();}set_pos_dir(x,y,unvisited);return 0;}//1==can 0==can'tint tell_can_unused(int x,int y){if(x>0 && (maze[x-1][y]==dirs[unused] ))return 0;if(x<N-1 && (maze[x+1][y]==dirs[unused] ))return 0;if(y>0 && (maze[x][y-1]==dirs[unused] ))return 0;if(y<N-1 && (maze[x][y+1]==dirs[unused] )) return 0;return 1;}void print_result(){printf("case %d-------\n",++result_num);print_maze();}void print_maze(){int i,j;for(i=0;i<N;i++){for(j=0;j<N;j++){char c = maze[i][j];if(c==0)printf(" ");elseprintf("%c ",c);}printf("\n");}printf("\n");}//find another unvisited node 1==found 0==not foundint get_next_node(int * nx,int *ny){int i,j;for(i=0;i<N;i++)for(j=0;j<N;j++){if(maze[i][j] == dirs[unvisited]){*nx = i;*ny = j;return 1;}}return 0;}// 1==found 0==not foundint get_partner(int x,int y,int dir){switch(dir){case up:x--;break;case down:x++;break;case left:y--;break;case right:y++;break;}//out of rangeif(x<0 || x>=N || y<0 || y>=N)return 0;if(0 != maze[x][y])return 0;return 1;}int set_pos_dir(int x,int y,int dir){maze[x][y] = dirs[dir];return 0;}
结果:
下面是3×3的结果,我用 >< 这样相对的箭头表示一个矩形,#表示不能填充,O表示空白。
- 迅雷一道上机题:nxn的方格,去掉一条对角线的两个对角...
- 方格(带对角线)的走法
- 编写函数将一个NxN的二维数组按“次对角线”翻转
- 迅雷的一道面试题目
- 输入两个数,第一个数决定一个nXn的矩阵
- [Java学习笔记]小练习_求矩阵对角线的和&清零对角线上的值
- 清华的一道复试上机题.......
- 找两个对角线顶点之间的路径
- nxn矩阵求和(对角线)
- 一道清华的上机题目
- 迅雷的一道笔试题解析
- 一道迅雷招聘海报上的题目
- 迅雷的一道机试题___URL解析
- 顺时针打印nxn的矩阵
- 一道迅雷笔试题
- 迅雷Java上机题
- 小鑫过河(优先队列+bfs) 字母重排 圆包含的方格个数 棋盘对角线穿越方格数
- 有关两个字符串匹配的一道题
- ajax中文处理
- BZOJ 3192([JLOI2013]删除物品-双堆转头并头队列)
- TOKEN_PRIVILEGES&LUID_AND_ATTRIBUTES structure
- 多线程切换以及线程进程之间关系
- poj 3252 Round Numbers 排列组合 杨辉三角
- 迅雷一道上机题:nxn的方格,去掉一条对角线的两个对角...
- 定制自己的操作系统(fedora,参照官方指南)
- Northcott Game + nim博弈
- 分页效果(无刷新)
- poj2777线段树+lazy思想
- 模板类要注意的地方
- SQL DDL & DML from Oracle JDBC toturial
- SQL Server 安装程序无法连接到数据库服务进行服务器配置。
- R.layout.main cannot be resolved