• [ABC193E] Oversleeping


    前言

    扩展欧几里得?几万年前学的东西,幸好最后写出来了,但还是值得复习一下(指水题解)

    题目

    AtCoder

    题目大意:

    (T) 组数据。

    时间从 (0) 时刻开始,有一辆火车从 (A) 地出发,在 (A) 地与 (B) 地之间来回跑,单趟时间为 (X) 秒,每到一个地点停 (Y) 秒。

    你初始在 (B) 地,先睡 (P) 秒,再醒着 (Q) 秒,一直循环。

    询问你是否可以上车,即是否存在一个时刻你醒着,且车停在 (B) 地。如果可以,输出最小的上车时间。如果不能,输出 infinity

    (1le Tle 10;1le X,Ple 10^9;1le Y,Qle 500.)

    讲解

    你看这个 (Y,Q) 这么小,一看就可以枚举,记为 (y,q)

    那么这就可以转换为一个同余方程问题,我们设火车经历 (i) 个周期,人经历 (j) 个周期,可列出方程:

    [X+i(2X+2Y)+y = Pj+Q(j-1)+q ]

    变形可得:

    [j(P+Q)-i(2X+2Y) = Q+X+y-q ]

    (a=P+Q,b=(2X+2Y),d=gcd(a,b)),于是用扩展欧几里得先求出特殊解,然后再找最小的时间即可。

    值得注意的是,(i,jge 0),但此时我们需要解的方程其实是:(aj-bi=kd),但扩欧解的方程是 (aj+bi=d),所以我们解出来的 (i) 需要满足小于等于 (0)

    找最小的时间其实就是找最大的 (iin(-infty,0]) 且最小的 (jin[0,+infty)),再根据他们算就行。

    实现其实不难。

    代码

    LL exgcd(LL a,LL b,LL &x,LL &y)
    {
    	if(!b)
    	{
    		x = 1;
    		y = 0;
    		return a;
    	}
    	LL ret = exgcd(b,a%b,y,x);
    	y -= x*(a/b);
    	return ret;
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	for(int T_T = Read(); T_T ;-- T_T)
    	{
    		X = Read(); Y = Read(); //on the way,stopping
    		P = Read(); Q = Read(); //asleep,awake
    		LL ans = INF,J,I;
    		LL d = exgcd(P+Q,2*(X+Y),J,I);
    		for(int y = 0;y < Y;++ y) 
    			for(int q = 0;q < Q;++ q)
    			{
    				LL deng = Q+X+y-q,i,j;
    				if(deng % d) continue;
    				j = J; i = I;
    				LL t1 = (P+Q) / d,t2 = 2*(X+Y) / d; i *= (deng / d); j *= (deng / d);
    				if(i > 0) 
    				{
    					LL woc = i / t1;
    					i -= woc * t1;
    					j += woc * t2; 
    				}
    				if(j < 0)
    				{
    					LL woc = (-j) / t2;
    					j += woc * t2;
    					i -= woc * t1;
    				}
    				while(i > 0 || j < 0) i = i - t1,j = j + t2;
    				LL wrng = Min((-i) / t1,j / t2);//both too large
    				i += wrng * t1;
    				ans = Min(ans,X+y+2*(-i)*(X+Y));
    			}
    		if(ans == INF) printf("infinity
    ");
    		else Put(ans,'
    ');
    	}
    	return 0;
    }
    /*
    草稿纸
    X+2iX+2iY+y = Pj+Q(j-1)+q
    X+2iX+2iY+y = Pj+Qj-Q+q
    2i(X+Y)-j(P+Q) = q-Q-X-y
    j(P+Q)-i(2X+2Y) = Q+X+y-q
    
    a(x+b)+b(y-a) = d
    k(a(x+b)+b(y-a)) = kd
    */
    
  • 相关阅读:
    HTML5存储
    HTML5 地理位置定位(Geolocation)原理及应用
    HTML5多媒体组件的使用
    HTML5拖拽
    HTML5一些总结
    js高级程序设计--数据类型
    JS高级程序设计基本概念
    浏览器内核、渲染引擎、js引擎
    JS高级程序设计笔记之script标签
    CenOS7下安装 nginx
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/14806488.html
Copyright © 2020-2023  润新知