UVA 11538 Chess Queen (数学)

ProblemAChess Queen
Input:
Standard Input

Output: Standard Output

You probably know how the game of chess is played and howchess queen operates. Two chess queens are in attacking position when they areon same row, column or diagonal of a chess board. Suppose two such chess queens(one black and the other white) are placed on (2x2) chess board. They can be inattacking positions in 12 ways, these are shown in the picture below:

UVA 11538 Chess Queen (数学)_第1张图片

Given an (NxM) board you will have to decide in howmany ways 2 queens can be in attacking position in that.

Input

Input file can contain up to 5000 lines of inputs. Each linecontains two non-negative integers which denote the value ofM and N (0< M, N£106) respectively.

Input is terminated by a line containing two zeroes. Thesetwo zeroes need not be processed.

Output

For each line of input produce one line of output. This linecontains an integer which denotes in how many ways two queens can be inattacking position in  an (MxN) board, where the values ofM and N came from the input. All output values will fit in 64-bit signedinteger.


SampleInput                              Outputfor Sample Input

2 2                                                                  

100 223

2300 1000

0 0

12

10907100

11514134000

Problemsetter: Shahriar Manzoor

Special Thanks to: Mohammad Mahmudur Rahman

 

分析:

因为只有两个皇后,因此相互攻击的方式只有两个皇后在同一行,同一列或同一对角线3中情况,这3中情况没有交集,因此可以采用加法原理,设在同一行放置两个皇后的方案数位A(n,m), 同一列放置两个皇后的方案数为B(n,m),在同一对角线放置两个皇后的方案数为D(n, m); 则答案为A(n, m)+B(n, m)+D(n, m);

A(n, m)的计算可以采用乘法原理,放白有n 种方法,放黑有(m-1)种方法,相乘就是n*m*(m-1);

B(n, m)计算的方法跟上述的一样,共有m*n*(n-1)种;

求D(n, m)的过程会稍微麻烦一些,不妨设n <= m 所有/向对角线,从左到右的长度依次为

1,2,3,4.....n-1, n, n.....n, n,n-1....4,3,2,1注意:共有(m-n+1)个n;

考虑到还有另一个方向的对角线,上面的整个结果还要乘以2,即:

公式有点变态,那个鸟符号我打不出来,所以公式就打不出来。。。嘻嘻

最后化简后的公式:

D(n, m) =2(m(n-1)(2n-4)/4 + (m-n+1)(n-1)m) = 2n(n-1)(3m-n-1)/3;

用加法原理就行啦。。


代码:

#include 
#include 
#include 
#include 
using namespace std;

typedef unsigned long long ULL;

int main()
{
    ULL n, m;
    while(~scanf("%lld %lld", &n, &m) && n || m) {
        if(n > m) swap(n, m);
        printf("%lld\n", n*m*(m+n-2)+2*n*(n-1)*(3*m-n-1)/3);
    }
    return 0;
}

你可能感兴趣的:(C/C++,算法编程)