zoukankan      html  css  js  c++  java
  • 给两个皇后找位置(数学递推)

    UVA 11538

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2533

    题解:在n * m的棋盘上给两个皇后找位置。横着找,竖着找,斜着找。

    先说个简单的东西:在一行n个棋盘给两个皇后找位置,确定一个皇后,再给另一个皇后找位置。第一个皇后有n个位置可选 ,确定后第二个皇后有n - 1个位置可选,所以总共有 n* (n - 1)种解。

    然后我们可以将这个问题转化为寻找棋盘上有多少这样的行,每行有多少个位置,就简单了。

    先预处理一下,将 i 个格子有  i * (i - 1)种解法存在数组 a[i] 中。

    先横着找:一行m个位置,共n行,所以有 n * a[m]种解法。

    再竖着找:一列n个位置,共m列,所以有 m * a[n]种解法。

    斜着找:这个就稍微麻烦一些了,不过没关系,慢慢来。

             先找个规律:从左上角开始画倾斜角为45度的斜线,我们可以发现,这些斜线经过的格子个数有个规律:1,2,3,4,···,n - 1,n ······n,n - 1,···,4,3,2,1

             所以我们可以写个从1到 n - 1的循环,将每条斜线对应的解的个数相加,结果  * 2,就是两头不相等斜线的解了。

             接着考虑中间有多少个n ,画图很容易发现是 (m - n) + 1 个。

             注意!这两个结果相加的解仅仅是一个方向的,还有倾斜角为135度的情况,所以这两个结果相加 * 2才是斜着找最后的结果。

    最后,将三种找法的结果相加即为所求。

    代码:

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<stack>
     7 #define ll long long
     8 using namespace std;
     9 
    10 ll a[1000005] = {0};
    11 
    12 int main()
    13 {
    14     
    15     a[1] = 0;
    16     for(ll i = 2; i <= 1000000; i++)
    17     {
    18         a[i] = i * (i - 1);
    19     }
    20     
    21     ll n, m;
    22     while(cin >> n >> m && n && m)
    23     {
    24         if(n > m) swap(n, m);
    25         ll ans = m * a[n];//竖着放 
    26         ans += n * a[m];//横着放 
    27         ans += (m - n + 1) * 2 * a[n];//斜着放而且是斜向格子数==n时 
    28         for(ll i = 2; i < n; i++)
    29         {
    30             ans +=  2 * 2 * a[i];//斜着放的不相等斜线
    31         }
    32         
    33         cout << ans << endl;
    34     }
    35     return 0;
    36 }
  • 相关阅读:
    编码问题
    Linux环境给文件重命名
    FIFO简记
    图像去模糊
    matlab直方图均衡,使用向量优化
    研究方向
    FPGA学习笔记之格雷码、边沿检测、门控时钟
    [转]关于凸优化的一些简单概念
    SSD果然劲爆!
    Qunie问题
  • 原文地址:https://www.cnblogs.com/xiaohanghuo/p/11360614.html
Copyright © 2011-2022 走看看