zoukankan      html  css  js  c++  java
  • UVA 11538 Chess Queen

    #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;
    }
  • 相关阅读:
    微信开发之注册公众号(二)
    我开通个人博客了~~~~
    微信开发之启用开发者模式(三)
    float浮动属性
    数组的定义与特点
    块级元素和行内元素
    对于if判断和switch选择的入门理解
    Form表单
    不知名的作业
    自我介绍
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/3395999.html
Copyright © 2011-2022 走看看