uva 11538 chess queen
題意
在一個 n∗m 的棋盤里放置兩枚皇后,每個皇后的攻擊範圍爲該行該列及對角線,問皇后會互相攻擊的方案數,兩個皇后視爲不同的棋子。
思路
對皇后的放置位置,我們可以分成三種情況。即在同一行,同一列,同一對角線。
在同一行的情況下,第一個皇后有
n∗m
種位置,第二個只有
(m−1)
種位置,即方案數爲
n∗m∗(m−1)
。
同理,在同一列的情況下的方案數是
n∗m∗(n−1)
。
而對於同一對角線的情況,我們要知道該對角線有多少個個字。單看主對角線的方向,我們有
n+m−1
條對角線,其長度爲序列
L=1,2,3,...,min(n,m)−1,min(n,m),...,min(n,m),min(n,m)−1,...,2,1
而對於長爲x的對角線,我們可以知道其方案數爲 x∗(x−1) 。
於是主對角線的答案是 (n<m)
∑x∈Lx∗(x−1)=2∗(∑j=1j=nj∗(j−1))+(m−n−1)∗n∗(n−1)
因爲輔對角線和主對角線是對稱的,所以上面的答案再乘以2。而上式中的求和可以用平方和公式和求和公式化簡。最後結果爲:
nm(n+m−2)+2(n(n+1)(2n+1)6−n(n+1)2)+(m−n−1)n(n−1)
code
#include <bits/stdc++.h>
using namespace std;
long long n, m;
int main () {
for (; scanf ("%lld%lld", &n, &m) == 2; ) {
if (n == 0 && m == 0) break;
long long ans = 0;
if (n > m) swap(n, m);
ans += n * (n + 1) * (2 * n + 1) / 6;
ans -= n * (n + 1) / 2;
ans *= 2;
ans += (m - n - 1) * n * (n - 1);
ans *= 2;
ans += n * m * (n - 1);
ans += n * m * (m - 1);
printf("%lld\n", ans);
}
return 0;
}