zoukankan      html  css  js  c++  java
  • hihoCoder 1584 Bounce 【数学规律】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)

    #1584 : Bounce

    时间限制:1000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    For Argo, it is very interesting watching a circle bouncing in a rectangle.

    As shown in the figure below, the rectangle is divided into N×M grids, and the circle fits exactly one grid.

    The bouncing rule is simple:

    1. The circle always starts from the left upper corner and moves towards lower right.

    2. If the circle touches any edge of the rectangle, it will bounce.

    3. If the circle reaches any corner of the rectangle after starting, it will stop there.

    Argo wants to know how many grids the circle will go through only once until it first reaches another corner. Can you help him?

    输入

    The input consists of multiple test cases. (Up to 105)

    For each test case:

    One line contains two integers N and M, indicating the number of rows and columns of the rectangle. (2 ≤ N, M ≤ 109)

    输出

    For each test case, output one line containing one integer, the number of grids that the circle will go through exactly once until it stops (the starting grid and the ending grid also count).

    样例输入
    2 2
    2 3
    3 4
    3 5
    4 5
    4 6
    4 7
    5 6
    5 7
    9 15
    样例输出
    2
    3
    5
    5
    7
    8
    7
    9
    11
    39

    题目链接:

      http://hihocoder.com/problemset/problem/1584

    题目大意:

      一个n*m的格子图,一个球从(1,1)开始延右下45°走,遇到边就反弹,直到走到四个角之一停止,问一路上只经过1次的格子数。

      (n,m<=109)

    题目思路:

      【数学规律】

      首先,由于反弹特性,我把球从网格中移到网格格线的交点上,于是图成了(n-1)*(m-1)的网格,球为点,左上角为(0,0)右下角为(n-1,m-1)

      然后将反弹操作变换成将网格对称折叠复制,如下图,这样就能知道,最后球停下来的时候一定位于([n-1,m-1],[n-1,m-1])([]为最小公倍数)

      所以我们知道了球一路上经过的格子总数为[n-1,m-1]+1((0,0)也要考虑),令d=gcd(n-1,m-1)

      再看重复经过的点,发现分别是d,2d,3d,...,其中还要扣掉位于边缘处的点(边缘处的点只可能经过一次)

      也就是扣掉(n-1),2(n-1),...,和(m-1),2(m-1),..

      所以总共经过多次的格子数为[n-1,m-1]/d-(n-1)/d-(m-1)/d+1(+1是因为(n-1,m-1)这个点不能算,不会出现重复扣是因为第一次重复的点就是终点)

      最终答案就是[n-1,m-1]+1-([n-1,m-1]/d-(n-1)/d-(m-1)/d+1)

     1 /****************************************************
     2 
     3     Author : Coolxxx
     4     Copyright 2017 by Coolxxx. All rights reserved.
     5     BLOG : http://blog.csdn.net/u010568270
     6 
     7 ****************************************************/
     8 #include<bits/stdc++.h>
     9 #pragma comment(linker,"/STACK:1024000000,1024000000")
    10 #define abs(a) ((a)>0?(a):(-(a)))
    11 #define lowbit(a) (a&(-a))
    12 #define sqr(a) ((a)*(a))
    13 #define mem(a,b) memset(a,b,sizeof(a))
    14 const double EPS=0.00001;
    15 const int J=10;
    16 const int MOD=1000000007;
    17 const int MAX=0x7f7f7f7f;
    18 const double PI=3.14159265358979323;
    19 const int N=150004;
    20 using namespace std;
    21 typedef long long LL;
    22 double anss;
    23 LL aans;
    24 int cas,cass;
    25 int n,m,lll,ans;
    26 LL gcd(LL a,LL b)
    27 {
    28     if(!b)return a;
    29     return gcd(b,a%b);
    30 }
    31 int main()
    32 {
    33     #ifndef ONLINE_JUDGE
    34     freopen("1.txt","r",stdin);
    35 //    freopen("2.txt","w",stdout);
    36     #endif
    37     int i,j,k;
    38     int x,y,z;
    39 //    for(scanf("%d",&cass);cass;cass--)
    40 //    init();
    41 //    for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
    42     while(~scanf("%d",&n))
    43     {
    44         scanf("%d",&m);
    45         n--,m--;
    46         LL d=gcd(n,m);
    47         aans=1LL*n*m/d;
    48         aans=aans-aans/d+n/d+m/d;
    49         printf("%lld
    ",aans);
    50     }
    51     return 0;
    52 }
    53 /*
    54 //
    55 
    56 //
    57 */
    View Code
  • 相关阅读:
    树、森林和二叉树的转换
    弱校ACM奋斗史
    安徽科技学院2016-2017-1学期2013信息与计算科学12班期末测试_题解
    安徽省2016“京胜杯”程序设计大赛_K_纸上谈兵
    安徽省2016“京胜杯”程序设计大赛_J_YZK的大别墅
    安徽省2016“京胜杯”程序设计大赛_I_恶魔A+B
    安徽省2016“京胜杯”程序设计大赛_H_单身晚会
    安徽省2016“京胜杯”程序设计大赛_G_木条染色
    安徽省2016“京胜杯”程序设计大赛_F_吃在工大
    LeetCode() Merge Intervals 还是有问题,留待,脑袋疼。
  • 原文地址:https://www.cnblogs.com/Coolxxx/p/7617198.html
Copyright © 2011-2022 走看看