#include <iostream> #include <stdio.h> #include <algorithm> /* 题意:棋盘n*m,问你有多少种放置两个相互攻击的皇后 先比较m和n值,若m>n,两者交换一下,即保证m<=n 分两种情况讨论: 1.两个皇后在同一直线上: 选定好一个皇后A,它可以摆放的位置有n*m种,由于两个皇后在同一直线上,另一个B只能摆放在(n-1+m-1)个位置。 所以总的种类为:n*m*(n+m-2),注意:这里不用再乘以二,因为我们先摆放A再摆放B的方案数其实已经包含了先摆放B再摆放A的方案数。 2.两个皇后在同一斜线上: 这种情况,两个皇后只能在一个i*i大小的正方形的两个对角线的两端,可以有四种摆放。(2<=i<=min(n,m)=m) 接下来,就枚举对应于某个值i,n*m的棋盘中有多少不同的i*i的方格,方案数为f(i)=(n-i+1)*(m-i+1) 展开来,再对不同的次数对应累加,得出sum=f(2)+f(3)+...+f(m)=4*((m-1)*n*m-m*(m-1)/2*n-m*(m-1)/2*m+(m-1)*m*(2*m-1)/6) 答案即为两者的和。 白书上求对角线的方案数的方法: 不妨设n<=m,所有/向对角线,从左到右的长度依次为: 1 2 3 ... n-1 n n ... n(m-n+1个n) n-1 ... 3 2 1 在长度为l的对角线上,摆放的方案数为l*(l-1)。 考虑到还有向的对角线,所以还要乘以2。 所以总的方案数为: 2*(sum{i*(i-1),2<=i<=n-1}+(m-n+1)*n*(n-1)); */ using namespace std; int main() { long long n,m; while(scanf("%lld%lld",&n,&m)!=EOF){ if(n==0 && m==0) break; if(n==0 || m==0) printf("0 "); if(m>n) swap(n,m); //printf("%lld %lld ",n,m); long long ans; ans=n*m*(n+m-2)+4*((m-1)*n*m-m*(m-1)/2*n-m*(m-1)/2*m+(m-1)*m*(2*m-1)/6); printf("%lld ",ans); } return 0; }