吴昊品游戏核心算法 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  }

你可能感兴趣的:(吴昊品游戏核心算法 Round 12(特别篇) —— 吴昊教你玩Block 3D(模拟))