1. 程式人生 > >press the button zoj 2018 ACM-ICPC qingdao

press the button zoj 2018 ACM-ICPC qingdao

本題題意 兩個人一個每隔a按b次 另一個每隔c按d次 無論按下多少次動作都是瞬間完成的

按下之後等亮v+0.5秒 總時間為t 時間結束時求counter的數值

 

這題的迴圈節是lcm 都是兩個時間的倍數嘛

在完整週期的總共按按鈕次數是 (t/a)*b+(t/c)*d

加上0秒的d+b-1

未滿週期的再算算

#include<iostream>
#include<vector>
#include<algorithm>
#include<cstdio>
using namespace std;
vector<long long> vec;

long long gcd(long long a,long long b)
{
	return b==0?a:gcd(b,a%b);
}

int main()
{
	long long all;
	cin>>all;
	while(all--)
	{
		long long a,b,c,d,v,t;
		cin>>a>>b>>c>>d>>v>>t;
		vec.clear();
		long long lcm=a*c/gcd(a,c);//一個週期是一個lcm 大家都可以達到那個倍數嘛 
		//將每次按按鈕的時間push進去 
		for(long long i=0;i<=lcm;i+=a)
		vec.push_back(i);
		for(long long i=0;i<=lcm;i+=c)
		vec.push_back(i);
		sort(vec.begin(),vec.end());
		vec.erase(unique(vec.begin(),vec.end()),vec.end());//將相同的時間段去除 為啥會有相同的時間出現? 因為這個相同的時間是兩個人都按了按鈕 
		long long re=0;//重新拍亮燈泡的次數 拍亮燈泡counter不記數 
		for(long long i=0;i<vec.size();i++)
		{
			if(vec[i]-vec[i-1]>v) re++; 
		}
		long long ans=(t/a)*b+(t/c)*d+b+d-1;
		ans-=t/lcm*re;// 有t/lcm個迴圈節 所以再乘上re就是完整迴圈週期的開燈次數了 
		long long last=t%lcm;//這是最後不足迴圈部分 
		for(long long i=1;vec[i]<last;i++)
		{
			if(vec[i]-vec[i-1]>v) ans--;//ans再次減掉拍亮的次數 
		}
		printf("%lld\n",ans);
	}
	return 0;
}