题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2533
题目大意:给定一个棋盘,在棋盘上放两个皇后(一白一黑),求使得两个皇后相互攻击(在一行、一列或对角线)的方案数。
解题思路:(挺有意思的一个题目)
1、我们首先可以想到的是一个皇后在一个任意的位置,另一个皇后可以放的在同一行或在同一列的方案数有(m-1+n-1),棋盘上一共有m*n个格子,所以可放在同行或同列相互攻击的方案是ans=(m-1+n-1)*m*n;
2、同行同列的方案数已经算出来了,现在我们计算对角线上的方案数吧,因为左斜和右斜的方案是一样多的,所以我们只要求出左斜线即可知道右斜线的方案数。
3、左斜线,首先我们要考虑到的是:斜线的最大值,即为min(m,n),那我们就把x=max(m,n)看作行,y=min(m,n)看作列,所以我们的2~y-1行每行的格子数就是行号数,大于等于y的行号数都只有y个格子,所以等于Y个格子的左斜线有(y-x+1)——每一条上可以任选两个点放置皇后,即for(LL i=2;i<m;i++) cnt+=(LL)i*(i-1)*2; cnt+=(LL)(n-m+1)*m*(m-1);
4、即总方案数:ans+2*cnt;
#include <cstdio> #include <cmath> #include <iostream> using namespace std; #define LL long long int main() { LL m,n; while(scanf("%lld%lld",&m,&n)==2&&(m+n)) { if(m>n) swap(m,n); LL ans=0,cnt=0; ans+=n*m*(n-1+m-1); for(LL i=2;i<m;i++) cnt+=(LL)i*(i-1)*2; cnt+=(LL)(n-m+1)*m*(m-1); ans+=cnt*2; printf("%lld ",ans); } return 0; }