Chess Queen uva11538 解题报告

Chess Queen uva11538 解题报告_第1张图片

这几天做了许多的搜索题,导致我一看到这道题立马就往搜索上想,一看数据规模瞬间吓尿,仔细一看才想起来原来是有规律的,也就是说可以写出公式,下面是分析过程。


1.题目中只有两个皇后q1,q2,且这两个皇后是有先后顺序的,我们假设有一条有n个位置的线段,然后将运用排列组合知识算出将两个不同的元素放在这条线段上共会产生多少种情况:首先在n个位置中选取一个,放置q1,有n种取法,再从剩下的n-1个位置选取一个位置放置q2,有n-1种取法,所以共有n(n-1)种取法,这是解题的核心

2.考虑水平方向和竖直方向,假设有n行,m列,且m>n,容易得出,水平方向有n*m*(m-1)种取法,竖直方向有n*m*(n-1)种取法

3.考虑对角方向,观察棋盘中对角线的长度,为 1,2,3...n-1,n,n,n...,n-1...3,2,1,共有m-n+1个n,所以对于长度为n的对角线来说,有n*(n-1)*(m-n+1)种取法,关键是1,2,3...n-1,我们需要计算0*1+1*2+2*3+...+(n-2)*(n-1),要想算出这个累加式,我们首先要知道

n(n+1)=[(n+2)(n+1)n-(n+1)n(n-1)]/3
知道了这个后我们就可以用列项相消的方法化简

1*2+2*3+3*4+...+n(n+1)
这个方程,这个方程的通向可以看成n(n+1),也就是n的范围是从1到n,按照我们事先知道的那个公式,这个式子可以展开为

(3*2*1-2*1*0)/3  +  (4*3*2-3*2*1)/3 +(5*4*3-4*3*2)/3 +...+[(n+2)(n+1)n-(n+1)n(n-1)]/3
可以发现从第二组数据开始,每一组数据的负项都会与之前的一个正项相消,而第一组数据的负项恰好是0,也就是说,算到随后一组数据,只会剩下一个正项,就是

(n+2)(n+1)n/3
然后,我们用n-2代替n代入我们求出的通项公式中,问题就得到解决了,即考虑斜对角的方向,有
2[2n(n-1)(n-2)/3]

括号里面的2是因为数据中本来就有两组1...n-1,外面的2是因为对角线有两个方向。

然后,我们就得到了一个完整的计算公式

2*(2*n*(n-1)*(n-2)/3+n*(n-1)*(m-n+1))+m*n*(m+n-2)

因为公式中的n是小于m的,所以输入数据的时候要处理一下,其实不管是n*m的棋盘还是m*n的棋盘,结果是一样的,所以n和m可以随意调换


#include <iostream>
using namespace std;
typedef long long ll;
ll n, m;
int main()
{
 while(cin>>n>>m)
 {
  if(n == 0 && m == 0) break;
  if(n > m) swap(n, m);
  cout<<2*(2*n*(n-1)*(n-2)/3+n*(n-1)*(m-n+1))+m*n*(m+n-2)<<endl;
 }
 return 0;
}














你可能感兴趣的:(详解,解题报告,组合数学,chess,Queen,uva11538)