迅雷一道上机题: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表示空白。  

原创粉丝点击