CodeForces 883A Automatic Door

本文解析了一道关于自动门开关次数的算法题,详细介绍了如何处理大规模员工和客户进出工厂的问题,通过枚举客户到达时间,计算门的开关次数,并考虑到员工到达间隔和门的关闭周期。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
 
 
A. Automatic Door
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

There is an automatic door at the entrance of a factory. The door works in the following way:

  • when one or several people come to the door and it is closed, the door immediately opens automatically and all people immediately come inside,
  • when one or several people come to the door and it is open, all people immediately come inside,
  • opened door immediately closes in d seconds after its opening,
  • if the door is closing and one or several people are coming to the door at the same moment, then all of them will have enough time to enter and only after that the door will close.

For example, if d = 3 and four people are coming at four different moments of time t1 = 4, t2 = 7, t3 = 9 and t4 = 13 then the door will open three times: at moments 4, 9 and 13. It will close at moments 7 and 12.

It is known that n employees will enter at moments a, 2·a, 3·a, ..., n·a (the value a is positive integer). Also m clients will enter at moments t1, t2, ..., tm.

Write program to find the number of times the automatic door will open. Assume that the door is initially closed.

Input

The first line contains four integers n, m, a and d (1 ≤ n, a ≤ 109, 1 ≤ m ≤ 105, 1 ≤ d ≤ 1018) — the number of the employees, the number of the clients, the moment of time when the first employee will come and the period of time in which the door closes.

The second line contains integer sequence t1, t2, ..., tm (1 ≤ ti ≤ 1018) — moments of time when clients will come. The values ti are given in non-decreasing order.

Output

Print the number of times the door will open.

Examples
Input
Copy
1 1 3 4
7
Output
Copy
1
Input
Copy
4 3 4 2
7 9 11
Output
Copy
4
Note

In the first example the only employee will come at moment 3. At this moment the door will open and will stay open until the moment 7. At the same moment of time the client will come, so at first he will enter and only after it the door will close. Thus the door will open one time.






 

这个题目的网上的题解是真的少,哈不容易自己写完,写篇博客帮助一下他人

先看数据量 n是1e9 ,m是1e5 所以我们要从m入手 ,m ,也就是人到来的时间,这个是可以枚举的

然后需要知道一个就是,    employees 到达的间隔是a,门开的时间是d  ,   门开一次可以通过的 employees 的数量是 d/a + 1  

然后就去枚举每个人,记录一个到目前为止,门什么时候关 ,用nowt表示

如果人到来的时间小于nowt的话,显然 continue 就行了

如果大于的话,就要考虑:  nowt  和    t[i] 之间 ,这个时间的间隔里,可能会有 employees 通过,怎么判断呢?

令 l=nowt/a    r = t[i] /a  分别表示到nowt为止通过的 employees 的数量,到t[i] 为止通过的 employees 的数量

如果他两一样,就说明时间间隔以内没有 employees 通过,直接 更新nowt 并且 ans++;

若果有的话,这个就要仔细的考虑一下了






 1 #include"bits/stdc++.h"
 2 
 3 using namespace std;
 4 typedef long long ll;
 5 
 6 ll n,m,a,d;
 7 
 8 ll t[200000];
 9 
10 int main()
11 {
12    cin>>n>>m>>a>>d;
13    for (int i=1;i<=m;i++)cin>>t[i];
14    ll nowt=0; ll ans=0;
15    ll k=d/a+1;
16    if(t[1]<a)nowt=t[1]+d; else nowt=a+d;
17    ++ans;
18    for (int i=1;i<=m;i++)
19    {
20           // cout<<i<<" "<<nowt<<" "<<ans<<endl;
21 
22       if(t[i]<=nowt)continue;
23       ll l=nowt/a,r=t[i]/a; r=min(r,n);
24       if(l==r)
25       {
26         nowt=t[i]+d;++ans;
27       }
28       else
29       {
30         ll t2;
31         ll t1=(r-l);
32         if(t1%k==0)t2=t1/k;
33         else t2=t1/k+1;  //  让所有的emploee 通过需要开几次门
34 ans+=t2; 35 l+=(t2-1)*k; 36 if((l+1)*a+d>=t[i]) 37 { 38 nowt=(l+1)*a+d; 39 } 40 else 41 { 42 nowt=t[i]+d; ans++; 43 } 44 } 45 46 // cout<<i<<" "<<nowt<<" "<<ans<<endl; 47 } 48 ll t1=nowt/a; 49 if(t1<n) 50 { 51 ll t2=(n-t1)/k ; 52 if((n-t1)%k==0) t2=(n-t1)/k; 53 else t2=(n-t1)/k+1; 54 ans+=t2; 55 } 56 57 cout<<ans; 58 59 60 61 62 63 64 65 66 67 }

 

 1 #include"bits/stdc++.h"
 2 
 3 using namespace std;
 4 typedef long long ll;
 5 
 6 ll n,m,a,d;
 7 
 8 ll t[200000];
 9 
10 int main()
11 {
12    cin>>n>>m>>a>>d;
13    for (int i=1;i<=m;i++)cin>>t[i];
14    ll nowt=0; ll ans=0;
15    ll k=d/a+1;
16    if(t[1]<a)nowt=t[1]+d; else nowt=a+d;
17    ++ans;
18    for (int i=1;i<=m;i++)
19    {
20           // cout<<i<<" "<<nowt<<" "<<ans<<endl;
21 
22       if(t[i]<=nowt)continue;
23       ll l=nowt/a,r=t[i]/a; r=min(r,n);
24       if(l==r)
25       {
26         nowt=t[i]+d;++ans;
27       }
28       else
29       {
30         ll t2;
31         ll t1=(r-l);
32         if(t1%k==0)t2=t1/k;
33         else t2=t1/k+1;
34         ans+=t2;
35        l+=(t2-1)*k;
36        if((l+1)*a+d>=t[i])
37        {
38           nowt=(l+1)*a+d;
39        }
40        else
41        {
42          nowt=t[i]+d; ans++;
43        }
44       }
45 
46      // cout<<i<<" "<<nowt<<" "<<ans<<endl;
47    }
48    ll t1=nowt/a;
49    if(t1<n)
50    {
51      ll t2=(n-t1)/k ;
52      if((n-t1)%k==0) t2=(n-t1)/k;
53      else t2=(n-t1)/k+1;
54      ans+=t2;
55    }
56 
57    cout<<ans;
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 }
View Code

 

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/zhangbuang/p/10686441.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值