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:
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;
}