4623. 买糖果
【优化】初始化sum为一圈能买的糖果的总价格,cnt为糖果数,每次枚举所有的a,如果当前sum+a在T的范围内,表示可以买,否则跳过当前的糖果,一趟下来之后。将T%sum,算出当前最多能买多少轮,然后再用剩下的T继续去枚举糖果。这样看起来是O(nT)的复杂度,但是其实每次T%sum后都是小于T/2的。证明如下:
如果当前sum > T/2,那么T%sum = T - sum < T / 2
如果当前sum < T/2, 那么T%sum < sum = T / 2
所以每次对T进行了二分,复杂度其实是O(nlongT)
// 10:15
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int arr[200001];
int main() {
ll n, t;
cin>>n>>t;
for (int i = 0; i < n; i++) cin>>arr[i];
ll sum = 0, d = 0, m = 0;
while (true) {
for (int j = 0; j < n; j++) {
if (d + arr[j] <= t) {
d += arr[j];
m++;
}
}
if (d == 0) break;
sum += (t / d) * m;
t %= d;
if (t == 0) break;
d = 0; m = 0;
}
cout<<sum<<endl;
}
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int main () {
ll n, t;
cin>>n>>t;
int arr[200005];
for (int i = 0; i < n; i++) cin>>arr[i];
ll ans = 0;
while (true) {
long s = 0, cnt = 0;
for (int i = 0; i < n; i++) {
if (s + arr[i] <= t) {
s += arr[i];
cnt++;
}
}
if (!cnt) break;
ans += t / s * cnt;
t %= s;
}
cout<<ans<<endl;
}