The 2018 ACM-ICPC Asia Qingdao Regional Contest J Press the Button

#题解
题目大意 两个人A和B A每a秒按开关b次 B每c秒按开关d次 灯泡亮v秒 总共时长t 问在t秒结束时计数器的值是多少
灯泡灭的时候按开关则会亮v+0.5秒 亮的时候按开关则计数器+1并且刷新亮时间到v+0.5秒
开场0秒的时候A和B都会去按开关

a和b的范围最大1e6 以a和b最小公倍数为一个周期 计算量不会超过1e6
计算每个周期计数器增加的量 乘上周期个数 加上不满一个周期的和第一次的即为答案
#AC代码

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;

ll gcd(ll a, ll b)
{
	if (!b)
		return a;
	return gcd(b, a % b);
}
int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
#endif
	int T;
	cin >> T;
	while (T--)
	{
		ll a, b, c, d, v, t;
		cin >> a >> b >> c >> d >> v >> t;
		ll g = a * c / gcd(a, c);
		ll x = 0, y = 0, last = 0, zq = 0, ans = b + d - 1;
		while (x < g || y < g)
		{
			if (x + a <= y + c)
			{
				x += a;
				if (x <= last + v)
					zq++;
				zq += b - 1;
				last = x;
			}
			else
			{
				y += c;
				if (y <= last + v)
					zq++;
				zq += d - 1;
				last = y;
			}
		}
		ans += zq * (t / g);
		t %= g;
		x = 0, y = 0, last = 0;
		while (x + a <= t || y + c <= t)
		{
			if (x + a <= y + c)
			{
				x += a;
				if (x <= last + v)
					ans++;
				ans += b - 1;
				last = x;
			}
			else
			{
				y += c;
				if (y <= last + v)
					ans++;
				ans += d - 1;
				last = y;
			}
		}
		printf("%lld\n", ans);
	}

	return 0;
}

猜你喜欢

转载自blog.csdn.net/CaprYang/article/details/82726373