UVA 11538 Chess Queen

题目链接: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;
}