• 11.12模拟考T2(GCD)


    2.梅花桩

      (blossom.pas/c/cpp)

    【问题描述】

        小x在练习一门轻功,这门轻功是在梅花桩上跳来跳去,这门轻功是严格按照直线从一个梅花桩直接跳到另外一个梅花桩上。因为小x有恐高症,所以除了开始和结束的两个梅花桩,这条直线上不能有其他梅花桩,否则小x会真气中断,直接掉下来。

        小x的梅花桩有W+1行,H+1列,每个梅花桩之间距离都是1米,严格按照上下左右排列,小x的轻功最少能跳L1米,最多能跳L2米。

        作为一位爱思考的数学青年,小x想到了一个问题:有多少对梅花桩对小x来说是安全的,或者说有多少对梅花桩能保证小x练习这门轻功。

    例如如下的地图:

    W = 2  H = 1

    **

    **

    **

    而小x跳跃的长度为2和3之间。

    这个梅花桩共有 (2+1) * (1+1) = 6个点以及有15 种配对方法

        (0,0)-(0,1)   (0,0)-(2,1)   (0,1)-(2,1)   (1,1)-(2,0)

        (0,0)-(1,0)   (0,1)-(1,0)   (1,0)-(1,1)   (1,1)-(2,1)

        (0,0)-(1,1)   (0,1)-(1,1)   (1,0)-(2,0)   (2,0)-(2,1)

        (0,0)-(2,0)   (0,1)-(2,0)   (1,0)-(2,1)

    在这之中,只有四种是可以满足小x跳跃长度的

             始位  末位 长度          始位  末位 长度

            (0,0)-(2,0) 2.00             (0,1)-(2,0) 2.24

            (0,0)-(2,1) 2.24             (0,1)-(2,1) 2.00

    但在这四种之中,(0,0)-(2,0)和(0,1)-(2,1)都不符合直线上没有其他梅花桩的要求,所以这个样例中只有2种结果。

    【输入】

    一行,4个整数W, H, L1, 和 L2

    【输出】

    一行。可能的方案数。

    【输入输出样例】

    blossom.in

    blossom.out

    2 1 2 3

    2

    【数据范围】

       50%数据 0<w,h,L1,L2<=100

       100% 数据  1 <= L1 <= L2 <= 1,500  1 <= W <= 1,000; 1 <= H <= 1,000

    思路:

    50%的分很好拿(四重循环)。

    但是如何拿满分?(这个问题好)HOW

    首先,如果L1<=1时,所有相邻为一的点都满足要求。

    if(l1<=1)
        ans=ans+w*(h+1)+h*(w+1);

    显然,当w=3,h=3时有(w+1)*h+h*(w+1);

    然后,就枚举(x,y)到(0,0)的距离。如果小于L2,大于L1则算出有多少那样的矩形*2.

    ans+=(w+1-x)*(h+1-y)

    cpp:

     1 #include<iostream>
     2 #include<string>
     3 #include<ctime>
     4 #include<cstdio>
     5 #include<cstdlib>
     6 #include<cmath>
     7 #include<cstring>
     8 #include<algorithm>
     9 #include<queue>
    10 #include<iomanip>
    11 using namespace std;
    12 const int maxn=5000001;
    13 int w,h,l1,l2;
    14 long long ans=0;
    15 int gcd(int a,int b)
    16 {
    17     return b==0?a:gcd(b,a%b);
    18 }
    19 
    20 int main()
    21 {
    22     freopen("blossom.in","r",stdin);
    23     freopen("blossom.out","w",stdout);
    24     ios::sync_with_stdio(false);
    25     cin>>w>>h>>l1>>l2;
    26     if(l1<=1)
    27         ans=ans+w*(h+1)+h*(w+1);
    28     for(int i=1;i<=w;i++)
    29     {
    30         for(int j=1;j<=h;j++)
    31         {
    32             int x=i*i+j*j;
    33             if(x>=l1*l1&&x<=l2*l2)
    34             {
    35                 x=gcd(i,j);
    36                 if(x==1)
    37                 {
    38                     ans=ans+(w-i+1)*(h-j+1)*2;
    39                 }
    40             }
    41         }
    42     }
    43     cout<<ans<<endl;
    44     return 0;
    45 }
    View Code
  • 相关阅读:
    Java知识系统回顾整理01基础04操作符02关系操作符
    Java知识系统回顾整理01基础04操作符01算术操作符
    Java知识系统回顾整理01基础03变量09块
    Java知识系统回顾整理01基础03变量08表达式
    Java知识系统回顾整理01基础03变量07final关键字
    Java知识系统回顾整理01基础03变量06变量的作用域
    Java知识系统回顾整理01基础03变量05变量命名规则
    Java知识系统回顾整理01基础03变量04类型转换
    leetcode-----64. 最小路径和
    leetcode-----63. 不同路径 II
  • 原文地址:https://www.cnblogs.com/zyker/p/6059558.html
Copyright © 2020-2023  润新知