1 solutions
-
1
题解 由于数据范围较大,所以使用普通枚举不能得到满分。因此考虑二分。
#include<bits/stdc++.h> using namespace std; int n; long long m,s,a[100005];//数据范围较大,使用long long bool check(long long x){//二分中决定范围的check函数 ,x表示等待的时间 ,x越大,完成或者正在进行收银的人越多 long long sum=0; for(int i=1;i<=n;i++){//依次枚举n个收银台 if(sum>m){ return true;//如果人数已经大于自身前面的人数,说明等待的时间过长(即x过大) } sum += x/a[i];//人数等于总时间除以收银台处理的时间 if (x % a[i] != 0) sum += 1;//向上取整 } if(sum>=m){ return true; } else return false; } int main(){ cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; } cin>>m; long long l=0,r=a[1]*m;//r为较大值 while(l+1<r){ long long mid=(l+r)/2; if(check(mid)){ r=mid;//若人数大于前方人数(包括自己),则说明mid较大,应将范围缩小至(l,mid] } else{ l=mid;//小于则反之 } } for(int i=1;i<=n;i++){ s += (r-1)/a[i];//计算s秒时,完成或者正在收银的人数。(r-1)表示进入收银台前 if ((r-1) % a[i] != 0) s += 1;//向上取整 } long long k=0; for(int i=1;i<=n;i++){ if((r-1)%a[i]==0){//若(r-1)除以a[i]的余数为零,说明在进入收银台前第i位收银台刚好为空。 k++;//由于前方可能还有人,空的收银台可以让出 } if(k+s==m){//当k+s=m时,说明已经到第一位并且有空的收银台 cout<<i; break; } } return 0; }
Hydro河中域第一篇题解
- 1
Information
- ID
- 3
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 4
- Tags
- # Submissions
- 66
- Accepted
- 7
- Uploaded By