花开雷霆崖 简单分治算法的应用

题目在这里,半年多以前做过的一道题了,印象比较深刻是因为那是某一天晚上突然在《算法竞赛入门经典》这本书上看到这个问题,刚好想起这道题当时不会做,就一时兴起把代码敲出来,WA了一次后debug了一会后就AC了。

花开雷霆崖

Time Limit:2000MS Memory Limit:65536KTotal Submit:10 Accepted:3

Description

雷霆崖上的牛头人酋长凯○•血蹄有一块荒芜的太阳花田,但是某一天,它发现花田上奇迹般的开了一朵奇迹之花!于是它兴冲冲的跑去暴风城买花,打算在花田上的其他地方也种满花。但是当他买好花以后却犯愁了,因为它家的花田是一 由2^k*2^k 个方格组成 的正方形,而买来的4种花形状又古怪(见下图描述),于是血蹄酋长想请您帮他想一个方法,让他可以把花田种满鲜花。

(4种花的形状分别对应1,2,3,4,种植的时候不能旋转或者翻转,0表示酋长最早发现的奇迹之花的形状)

Input

多组数据测试,直到文件结束(EOF)每行一个K,N,M,分别代表花田的大小(长宽均为2的K次方,1<=K<=9),奇迹之花位于N行M列

Output

0表示奇迹之花的位置,1表示此格上中的是第一种花,2表示此格上中的是第二种花,以此类推。每组数据一个输出,然后输出一个换行。

Sample Input

1 0 13 7 6

Sample Output

30331122112211121222311122243311124411311122133311123334312233443302

Hint

对于第一组数据,图如下:对于第二组数据,香港空间,图如下:

花田的面积是2^k * 2^k,所以如果把花田切割成4个小正方形,就变成4个2^(k-1) * 2^(k-1)的正方形了,可以知道4个中的其中一个必定会有一个有奇迹之花,再把这个有奇迹之花的正方形切割成4个,这样一直递归下去,最后可以得到一个2*2的带有奇迹之花的正方形。现在的问题是,每次切割的时候,另外三个没有奇迹之花的正方形要怎么处理?方法很简单,香港服务器,就是给他构造一个,三个刚好可以凑成一种花的形状。例如第一次切割的时候可以把中间的那块看成是奇迹之花:

后面的以此类推,最后就能得出正确答案。

思路很清晰,网站空间,但是中间的步骤还是挺多的,代码量还是挺多的,细节要注意。我的代码有点繁琐,很多if……else

View Code

#include<stdio.h>#include<math.h>#include<string.h>int k,n,m,t,side;int map[1000][1000];void func(int x,int y,int ax,int ay,int length){int midx,midy;length/=2;midx=x+length-1;midy=y+length-1;if(length==1){if(x==ax){if(y==ay)map[ay][ax+1]=map[ay+1][x]=map[ay+1][ax+1]=4;elsemap[ay][ax+1]=map[ay-1][x]=map[ay-1][ax+1]=2;}else{if(y==ay)map[ay][ax-1]=map[ay+1][ax]=map[ay+1][ax-1]=3;elsemap[ay][ax-1]=map[ay-1][ax]=map[ay-1][ax-1]=1;}}else{if(ax<=midx&&ay<=midy){map[midy][midx+1]=map[midy+1][midx]=map[midy+1][midx+1]=4;func(x+length,y,midx+1,midy,length);func(x,y+length,midx,midy+1,length);func(x+length,y+length,midx+1,midy+1,length);func(x,y,ax,ay,length);}else if(ax<=midx&&ay>midy){map[midy][midx]=map[midy][midx+1]=map[midy+1][midx+1]=2;func(x,y,midx,midy,length);func(x+length,y+length,midx+1,midy+1,length);func(x+length,y,midx+1,midy,length);func(x,y+length,ax,ay,length);}else if(ax>midx&&ay<=midy){map[midy][midx]=map[midy+1][midx]=map[midy+1][midx+1]=3;func(x,y,midx,midy,length);func(x,y+length,midx,midy+1,length);func(x+length,y+length,midx+1,midy+1,length);func(x+length,y,ax,ay,length);}else{map[midy][midx]=map[midy+1][midx]=map[midy][midx+1]=1;func(x,y,midx,midy,length);func(x,y+length,midx,midy+1,length);func(x+length,y,midx+1,midy,length);func(x+length,y+length,ax,ay,length);}}}void main(){int i,j;,&k,&n,&m)!=EOF){memset(map,0,sizeof(map));n++;m++;map[n][m]=0;t=pow(2,k);func(1,1,m,n,t);map[n][m]=0;for(i=1;i<=t;i++){for(j=1;j<=t;j++)printf(,map[i][j]);printf();}printf();}}

告诉自己,我这次失败了,

花开雷霆崖 简单分治算法的应用

相关文章:

你感兴趣的文章:

标签云: