吴昊品游戏核心算法 Round 12(特别篇) —— 吴昊教你玩Block 3D(模拟)

砖块游戏有很多种,比如“拼砖块”,“打砖块”,“推 砖块”等等,我们这里要做的是“叠砖块”。游戏的条件应该已经很明了了,如果再不明了的话,我还附上一张图(如下图所示),我们这里用一个简单的示例来模 拟这个游戏。我们假设一共有六种砖块,即1*1到6*6,而每一种砖块的数量是有限个的。我们的输入每一行只有六个数字,分别表示从1*1到6*6的这六 种砖块的个数。

 

  由于如果不是同时放置,而是具有先后顺序的放置的话,我们需要考虑到一种策略的问题,这里的AI就有实现地聪明与愚蠢之分了,我们这里考虑一个更为简单的 AI,也就是说,所有的砖块是可以由玩家自己来考虑放置的先后顺序的,这样做的话,也就避免了复杂程度过高的AI。我们这里考虑一种“集装箱”,也就是 说,我们需要将这所有的砖块叠放在底面积6*6的集装箱中,如果集装箱的数目不够的话,我们需要增加其高度,直到将集装箱的个数可以将所有的砖块包装好。 我们的这个AI小插件可以输出集装箱所需要的最小高度(这里假设每个小砖块的高度与集装箱的高度是相等的)。

 这里的逻辑比较复杂,还是考虑到底面积为6*6的情况,如果再提高一下的话,也许会更为复杂,现在暂时就由6*6开始分析起(可以考虑通过逐渐增加底面积的大小来将游戏的难度增加,这当然也是一种思路)

 推理:

 (1)如果是6*6的话,会占用一个完整的箱子,并且没有剩余的空间,情况很简单。

 (2)5*5的砖块需要占用一个箱子,并且有11个可以盛放1*1的砖块的空间。

 (3)4*4的砖块可以占用一个箱子,并且可以留下5个可以盛放2*2的砖块的空间。

 (4)3*3的砖块比较复杂,需要分成四种情况来讨论,在Solve的时候专门为这种情况重新开了一个数组。为什么要分四种情况呢?这主要是由于4K+n中的(n=0,1,2,3)

 (5)2*2和1*1的情况比较简单,这里就不继续讨论了,先填满大的再填满小的就可以了。

 Solve:

 
 1  #include<stdio.h>
 2  
 3  int main()
 4  {
 5    //考虑到1*1和2*2砖块的特殊性,这里单独开设两个变量来计数
 6    //来计数一个集装箱的1*1的空位数目和2*2的空位数目
 7    int x,y;
 8    //存储需要的集装箱的总数目    
 9    int N;
10    //从1*1到6*6这六种砖块的个数
11    int a,b,c,d,e,f;
12    //对于3*3这种砖块,必须分析一下其为4k+n(0<=n<=3)的四种情况
13    //这里对应的是2*2的砖块可以放下的数目
14    int u[4]={0,5,3,1};
15    while(1)
16    {
17      scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&e,&f);
18      //这里考虑一个退出的情况
19      if(a==0&&b==0&&c==0&&d==0&&e==0&&f==0break;
20      //(c+3)/4是一个技巧,因为开1--4个3*3的砖块都是等权的
21      N=f+e+d+(c+3)/4;
22      //这里的y是通过4*4的砖块数目和3*3的砖块数目分析得出的
23      y=5*d+u[c%4];        
24      //分析2*2的增加,这个与前面的3*3用的是相同的技巧
25      if(b>y) N+=(b-y+8)/9;
26      x=36*N-36*f-25*e-16*d-9*c-4*b;
27      //分析1*1的增加,这种情况,同理了
28      if(a>x) N+=(a-x+35)/36;
29      printf("%d\n",N);
30    }
31    return 0;
32  }

posted on 2013-02-28 14:31  吴昊系列  阅读(220)  评论(0编辑  收藏  举报

导航