Mysterious Light(数学)

问题 B: Mysterious Light

时间限制: 2 Sec   内存限制: 256 MB
提交: 208   解决: 54
[ 提交][ 状态][ 讨论版][命题人: admin]

题目描述

Snuke is conducting an optical experiment using mirrors and his new invention, the rifle of Mysterious Light.

Three mirrors of length N are set so that they form an equilateral triangle. Let the vertices of the triangle be a,b and c.

Inside the triangle, the rifle is placed at the point p on segment ab such that ap=X. (The size of the rifle is negligible.) Now, the rifle is about to fire a ray of Mysterious Light in the direction of bc.

The ray of Mysterious Light will travel in a straight line, and will be reflected by mirrors, in the same ways as "ordinary" light. There is one major difference, though: it will be also reflected by its own trajectory as if it is a mirror! When the ray comes back to the rifle, the ray will be absorbed.

The following image shows the ray's trajectory where N=5 and X=2.
It can be shown that the ray eventually comes back to the rifle and is absorbed, regardless of the values of N and X. Find the total length of the ray's trajectory.

Constraints
2≦N≦1012
1≦X≦N−1
N and X are integers.
Partial Points
300 points will be awarded for passing the test set satisfying N≦1000.
Another 200 points will be awarded for passing the test set without additional constraints.

输入

The input is given from Standard Input in the following format:N X

输出

Print the total length of the ray's trajectory.

样例输入

5 2

样例输出

12

题意:从正三角形的一条边沿bc方向发出一道光线,光线遇见正三角形的边或者自己的轨迹都能发生反射,直到回到起点,求光路的长度。

题解:可以模拟一下,发现问题存在子问题,每次反射后构成的平行四边形的边长N能否取余放射出的正三角形的边长X(不同于一开始的n和x),若能取余,则最终一定可以从平行四边形的入口出去(就是一开始反射的起点),则可一步步递归到最终能取余的情况,再返回来。

#include
#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define INF 0x3f3f3f3f
#define FAST_IO ios::sync_with_stdio(false)
const double PI = acos(-1.0);
const double eps = 1e-6;
const int MAX=1e5+10;
const int mod=1e9+7;
typedef long long ll;
using namespace std;
#define gcd(a,b) __gcd(a,b)
inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
inline ll qpow(ll a,ll b){ll r=1,t=a; while(b){if(b&1)r=(r*t)%mod;b>>=1;t=(t*t)%mod;}return r;}
inline ll inv1(ll b){return qpow(b,mod-2);}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll r=exgcd(b,a%b,y,x);y-=(a/b)*x;return r;}
inline ll read(){ll x=0,f=1;char c=getchar();for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;for(;isdigit(c);c=getchar()) x=x*10+c-'0';return x*f;}

long long n, x,ans;
ll gcdgcd(ll x,ll n)
{
    if(n%x==0)
        return n*2-x;
    ans=n/x*x*2+gcdgcd(n%x, x);
    return ans;
}

int main()
{
    cin>>n>>x;
    cout<

你可能感兴趣的:(数论,思维,模拟+xx)