NOJ——[1378] 战斗吧!皇后们!

  • 时间限制: 1000 ms 内存限制: 65535 K
  • 问题描述
  • 我们都知道N皇后问题吧(ACM超级经典的题目,不知道的话 在我们oj找找看吧)!现在我们简单一下问题,只要两个皇后,而且我们还要
    这两个皇后斗争吧~2012都过去了,让我们决一死战吧~
  • 输入
  • 问题有多个案例。
    每个案例存在n,m,代表n*m的一个棋盘。(0<=n,m<=10^6)
    当n=m=0,表示输入结束。
  • 输出
  • 输出在n*m棋盘上两个皇后互相攻击的总共可能数。
  • 样例输入
  • 1 2
    2 2
    100 223
  • 样例输出
  • 2
    12
    10907100
  • 提示
  • 建议使用__int64
  • 来源
  • Three God

个人认为这道题比较有意思,如果能攻击,位置不外乎是同一行,同一列,同一对角线,设矩阵为n*m,那么,前面2者的可能性就是(m+n-2)*n*m;

如果是在对角线,看图


NOJ——[1378] 战斗吧!皇后们!_第1张图片
 
 这是3*5的情况时主对角线的可能性,
再看图
NOJ——[1378] 战斗吧!皇后们!_第2张图片
这是4*5的情况,
我们先从行考虑,那么就是有2,3,4,.......n,每种情况方案是A(2,n),
再看列,如果当前第i列比n大,那么方案是A(2,n),否则就是A(2,i);
但注意我这种方法是基于n<=m的,所以输入后要判断是不是要交换

#include<stdio.h>
#include<math.h>

int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
if(!m && !n)
break;
__int64 ret=(__int64)(m+n-2)*n*m;
if(n>m)
{
n=n^m;
m=n^m;
n=n^m;
}
for(int i=2;i<=n;i++)
ret+=(__int64)2*i*(i-1);
for(int i=m-1;i>=2;i--)
if(i>n)
ret+=(__int64)2*n*(n-1);
else
ret+=(__int64)2*i*(i-1);
printf("%I64d\n",ret);
}
return 0;
}


你可能感兴趣的:(NOJ——[1378] 战斗吧!皇后们!)