1. 程式人生 > >hihoCoder 1584 Bounce 【數學規律】 (ACM-ICPC國際大學生程序設計競賽北京賽區(2017)網絡賽)

hihoCoder 1584 Bounce 【數學規律】 (ACM-ICPC國際大學生程序設計競賽北京賽區(2017)網絡賽)

media while def closed edge hiho problem reserve acm

#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\n",aans);
50     }
51     return 0;
52 }
53 /*
54 //
55 
56 //
57 */
View Code

hihoCoder 1584 Bounce 【數學規律】 (ACM-ICPC國際大學生程序設計競賽北京賽區(2017)網絡賽)