在国际象棋中,一个玩家可以拥有不同的材料组合,例如:
“1个女王,2个骑士,2个骑士,2个主教,8个典当+国王”是一个组合如果玩家失去一位主教:
“1个女王,2个骑士,2个骑士,1个主教,8个典当+国王”是另一个组合
..之后,如果一个兵被提升为骑士,那么:
“1个女王,2个车手,3个骑士,1个主教,7个棋子+国王”是另一个组合好的,以下组合无效:
“5个女王,5个车,5个骑士,5个主教,2个棋子+国王”
因为缺乏促进的棋子。 (5个皇后=需要4个兵)(5个车队=需要3个兵)等等,所以需要4 + 3 + 3 + 3 = 13个兵。由于棋盘上有2个棋子,因此最多可以推广6个棋子。无效。
有多少有效的材料组合? 我使用以下C代码计算了8694个组合。问题是:
您是否找到更简单/有效的算法来计算它? (更少的周期,更少的计算,更清晰的代码等)......甚至数学公式??
total = 0;
for (queens=0;queens<=9;queens++)
for (rooks=0;rooks<=10;rooks++)
for (bishops=0;bishops<=10;bishops++)
for (knights=0;knights<=10;knights++)
for (pawns=0;pawns<=8;pawns++)
{
pawnsRequested = 0;
if (queens>1) pawnsRequested += queens - 1;
if (rooks>2) pawnsRequested += rooks - 2;
if (bishops>2) pawnsRequested += bishops - 2;
if (knights>2) pawnsRequested += knights - 2;
if (8-pawns < pawnsRequested) continue;
total++;
}
printf("%i\n",total);
答案 0 :(得分:1)
如果作品类型是独立的,那么我们可以简单地加倍:皇后的10种可能性乘车时间的11种可能性等等。然而,我们需要跟踪典当用法。这里有一个名为generating functions的数学技巧,我们可以对其进行编码,例如,白车作为
3 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8,
其中x
的幂表示所使用的棋子数,系数表示可能性的数量。在这里,有三种可能性,不需要促销的棋子(0,1,2),一个需要一个晋升的棋子(3),一个需要两个晋升的棋子(4)等等。现在我们可以将每个因素相乘(分别是女王,车手,主教,骑士,典当)。
(2 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8)
* (3 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8)
* (3 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8)
* (3 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8)
* (1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8)
1
到x^8
的系数,即所需0
到8
个卒子的可能性数量,分别为54,135,261,443,693, 1024,1450,1986,2648,总结为8694。